home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / dalla rivista / host contacted / jikes.lha / jikes-1.11 / src / bytecode.cpp < prev    next >
C/C++ Source or Header  |  2000-01-06  |  203KB  |  5,463 lines

  1. // $Id: bytecode.cpp,v 1.43 2000/01/06 06:46:47 lord Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10.  
  11. #include "assert.h"
  12. #include "config.h"
  13. #include "ast.h"
  14. #include "bytecode.h"
  15. #include "class.h"
  16. #include "control.h"
  17. #include "semantic.h"
  18. #include "stream.h"
  19. #include "symbol.h"
  20. #include "table.h"
  21. #include <iostream.h>
  22. #include <string.h>
  23.  
  24. #ifdef HAVE_WCHAR_H
  25. # include <wchar.h>
  26. #endif
  27.  
  28. #ifdef WIN32_FILE_SYSTEM
  29. #include <windows.h>
  30. #endif
  31.  
  32. void ByteCode::CompileClass()
  33. {
  34.     AstClassDeclaration *class_decl = unit_type -> declaration -> ClassDeclarationCast();
  35.     AstClassBody *class_body = (class_decl
  36.                                      ? class_decl -> class_body
  37.                                      : ((AstClassInstanceCreationExpression *) unit_type -> declaration) -> class_body_opt);
  38.  
  39.     //
  40.     // Process static variables.
  41.     //
  42.     Tuple<AstVariableDeclarator *> initialized_static_fields(unit_type -> NumVariableSymbols()); // fields needing code to initialize
  43.     {
  44.         for (int i = 0; i < class_body -> NumClassVariables(); i++)
  45.         {
  46.             AstFieldDeclaration *field_decl = class_body -> ClassVariable(i);
  47.             for (int vi = 0; vi < field_decl -> NumVariableDeclarators(); vi++)
  48.             {
  49.                 AstVariableDeclarator *variable_declarator = field_decl -> VariableDeclarator(vi);
  50.                 VariableSymbol *vsym = variable_declarator -> symbol;
  51.                 DeclareField(vsym);
  52.  
  53.                 //
  54.                 // We need a static constructor-initializer if we encounter at least one class
  55.                 // variable that is declared with an initializer that is not a constant expression.
  56.                 //
  57.                 if (variable_declarator -> variable_initializer_opt)
  58.                 {
  59.                     AstExpression *init = variable_declarator -> variable_initializer_opt -> ExpressionCast();
  60.                     if (! (init && init -> IsConstant()))
  61.                         initialized_static_fields.Next() = variable_declarator;
  62.  
  63.                     //
  64.                     // TODO: there seems to be a contradiction between the language spec and the VM spec.
  65.                     // The language spec seems to require that a variable be initialized (in the class file)
  66.                     // with a "ConstantValue" only if it is static. The VM spec, on the other hand, states
  67.                     // that a static need not be final to be initialized with a ConstantValue.
  68.                     // As of now, we are following the language spec - ergo, this extra test.
  69.                     //
  70.                     else
  71.                     {
  72.                         assert(variable_declarator -> symbol);
  73.                         if (! variable_declarator -> symbol -> ACC_FINAL())
  74.                             initialized_static_fields.Next() = variable_declarator;
  75.                     }
  76.                 }
  77.             }
  78.         }
  79.     }
  80.  
  81.     //
  82.     // Process instance variables.
  83.     //
  84.     Tuple<AstVariableDeclarator *> initialized_instance_fields(unit_type -> NumVariableSymbols()); // fields needing code to init
  85.     {
  86.         for (int i = 0; i < class_body -> NumInstanceVariables(); i++)
  87.         {
  88.             AstFieldDeclaration *field_decl  = class_body -> InstanceVariable(i);
  89.             for (int vi = 0; vi < field_decl -> NumVariableDeclarators(); vi++)
  90.             {
  91.                 AstVariableDeclarator *vd = field_decl -> VariableDeclarator(vi);
  92.                 DeclareField(vd -> symbol);
  93.  
  94.                 //
  95.                 // must set Constant attribute if initial value specified
  96.                 //
  97.                 if (vd -> variable_initializer_opt)
  98.                     initialized_instance_fields.Next() = vd;
  99.             }
  100.         }
  101.     }
  102.  
  103.     //
  104.     // supply needed field declaration for this$0 and any additional local shadow parameters
  105.     //
  106.     {
  107.         for (int i = 0; i < unit_type -> NumConstructorParameters(); i++)
  108.             DeclareField(unit_type -> ConstructorParameter(i));
  109.     }
  110.  
  111.     //
  112.     // supply needed field declaration for enclosing instances (this$n, n > 0) if present
  113.     //
  114.     {
  115.         for (int i = 1; i < unit_type -> NumEnclosingInstances(); i++)
  116.             DeclareField(unit_type -> EnclosingInstance(i));
  117.     }
  118.  
  119.     //
  120.     // supply needed field declarations for "class " identifiers (used for X.class literals) if present
  121.     //
  122.     {
  123.         for (int i = 0; i < unit_type -> NumClassLiterals(); i++)
  124.             DeclareField(unit_type -> ClassLiteral(i));
  125.     }
  126.  
  127.     //
  128.     // compile method bodies
  129.     //
  130.     {
  131.         for (int i = 0; i < class_body -> NumMethods(); i++)
  132.         {
  133.             AstMethodDeclaration *method = class_body -> Method(i);
  134.             if (method -> method_symbol)
  135.             {
  136.                 int method_index = methods.NextIndex(); // index for method
  137.  
  138.                 BeginMethod(method_index, method -> method_symbol);
  139.                 AstBlock *method_block = method -> method_body -> BlockCast();
  140.                 if (method_block) // not an abstract method ?
  141.                     EmitStatement(method_block);
  142.                 EndMethod(method_index, method -> method_symbol);
  143.             }
  144.         }
  145.     }
  146.  
  147.     //
  148.     // NOTE that an abstract class that requires this patch may become out-of-date
  149.     // and cause spurious messages to be emitted if any abstract method inherited
  150.     // from an interface is later removed from that interface.
  151.     //
  152.     if (unit_type -> ACC_ABSTRACT())
  153.     {
  154.         for (int i = 0; i < unit_type -> expanded_method_table -> symbol_pool.Length(); i++)
  155.         {
  156.             MethodShadowSymbol *method_shadow_symbol = unit_type -> expanded_method_table -> symbol_pool[i];
  157.             MethodSymbol *method_symbol = method_shadow_symbol -> method_symbol;
  158.             if (method_symbol -> ACC_ABSTRACT() &&
  159.                 method_symbol -> containing_type != unit_type &&
  160.                 method_symbol -> containing_type -> ACC_INTERFACE())
  161.             {
  162.                 if (! method_symbol -> IsTyped())
  163.                     method_symbol -> ProcessMethodSignature(&this_semantic, class_decl -> identifier_token);
  164.                 method_symbol -> ProcessMethodThrows(&this_semantic, class_decl -> identifier_token);
  165.  
  166.                 int method_index = methods.NextIndex();
  167.  
  168.                 BeginMethod(method_index, method_symbol);
  169.                 EndMethod(method_index, method_symbol);
  170.             }
  171.         }
  172.     }
  173.  
  174.     //
  175.     // compile any private access methods
  176.     //
  177.     {
  178.         for (int i = 0; i < unit_type -> NumPrivateAccessMethods(); i++)
  179.         {
  180.             int method_index = methods.NextIndex(); // index for method
  181.  
  182.             MethodSymbol *method_sym = unit_type -> PrivateAccessMethod(i);
  183.             BeginMethod(method_index, method_sym);
  184.             GenerateAccessMethod(method_sym);
  185.             EndMethod(method_index, method_sym);
  186.         }
  187.     }
  188.  
  189.     //
  190.     //
  191.     //
  192.     MethodSymbol *class_literal_sym = unit_type -> ClassLiteralMethod();
  193.     if (class_literal_sym)
  194.     {
  195.         //
  196.         // Generate the class$ identity method used for class literal-related garbage mumbo-jumbo initialization
  197.         //
  198.         int method_index = methods.NextIndex(); // index for method
  199.         BeginMethod(method_index, class_literal_sym);
  200.         GenerateClassAccessMethod(class_literal_sym);
  201.         EndMethod(method_index, class_literal_sym);
  202.     }
  203.  
  204.     //
  205.     //
  206.     //
  207.     MethodSymbol *block_init_method = unit_type -> block_initializer_method;
  208.     if (block_init_method)
  209.     {
  210.         int method_index = methods.NextIndex(); // index for method
  211.         BeginMethod(method_index, block_init_method);
  212.  
  213.         int fi = 0,
  214.             bi = 0;
  215.         while (fi < initialized_instance_fields.Length() && bi < class_body -> NumBlocks())
  216.         {
  217.             if (initialized_instance_fields[fi] -> LeftToken() < class_body -> Block(bi) -> left_brace_token)
  218.                  InitializeInstanceVariable(initialized_instance_fields[fi++]);
  219.             else EmitStatement(class_body -> Block(bi++));
  220.         }
  221.  
  222.         while (fi < initialized_instance_fields.Length())
  223.             InitializeInstanceVariable(initialized_instance_fields[fi++]);
  224.  
  225.         //
  226.         // compile any initialization blocks
  227.         //
  228.         while (bi < class_body -> NumBlocks())
  229.             EmitStatement(class_body -> Block(bi++));
  230.  
  231.         PutOp(OP_RETURN);
  232.         EndMethod(method_index, block_init_method);
  233.     }
  234.  
  235.     //
  236.     //
  237.     //
  238.     if (unit_type -> NumGeneratedConstructors() == 0)
  239.     {
  240.         if (class_body -> default_constructor)
  241.             CompileConstructor(class_body -> default_constructor, initialized_instance_fields);
  242.         else
  243.         {
  244.             for (int i = 0; i < class_body -> NumConstructors(); i++)
  245.             {
  246.                 AstConstructorDeclaration *constructor = class_body -> Constructor(i);
  247.                 CompileConstructor(constructor, initialized_instance_fields);
  248.             }
  249.  
  250.             for (int k = 0; k < unit_type -> NumPrivateAccessConstructors(); k++)
  251.             {
  252.                 MethodSymbol *constructor_sym = unit_type -> PrivateAccessConstructor(k);
  253.                 AstConstructorDeclaration *constructor =
  254.                        constructor_sym -> method_or_constructor_declaration -> ConstructorDeclarationCast();
  255.                 CompileConstructor(constructor, initialized_instance_fields);
  256.             }
  257.         }
  258.     }
  259.     else
  260.     {
  261.         for (int i = 0; i < unit_type -> NumGeneratedConstructors(); i++)
  262.         {
  263.             MethodSymbol *this_constructor_symbol = unit_type -> GeneratedConstructor(i);
  264.             AstConstructorDeclaration *constructor =
  265.                     this_constructor_symbol -> method_or_constructor_declaration -> ConstructorDeclarationCast();
  266.             AstConstructorBlock *constructor_block = constructor -> constructor_body -> ConstructorBlockCast();
  267.  
  268.             //
  269.             // compile generated constructor
  270.             //
  271.             int method_index = methods.NextIndex(); // index for method
  272.             BeginMethod(method_index, this_constructor_symbol);
  273.  
  274.             assert(constructor_block -> explicit_constructor_invocation_opt);
  275.  
  276.             EmitStatement((AstStatement *) constructor_block -> explicit_constructor_invocation_opt);
  277.  
  278.             for (int si = 0; si < constructor_block -> NumLocalInitStatements(); si++)
  279.                 EmitStatement(constructor_block -> LocalInitStatement(si));
  280.  
  281.             //
  282.             // supply needed field initialization unless constructor
  283.             // starts with explicit 'this' call to another constructor
  284.             //
  285.             if (! (constructor_block -> explicit_constructor_invocation_opt &&
  286.                    constructor_block -> explicit_constructor_invocation_opt -> ThisCallCast()))
  287.             {
  288.                 if (unit_type -> NumEnclosingInstances())
  289.                 {
  290.                     VariableSymbol *this0_parameter = unit_type -> EnclosingInstance(0);
  291.                     PutOp(OP_ALOAD_0); // load address of object on which method is to be invoked
  292.                     LoadLocal(1, this0_parameter -> Type());
  293.                     PutOp(OP_PUTFIELD);
  294.                     PutU2(RegisterFieldref(this0_parameter));
  295.                 }
  296.  
  297.                 if (class_body -> this_block)
  298.                 {
  299.                     AstBlock *block = class_body -> this_block;
  300.                     for (int si = 0; si < block -> NumStatements(); si++)
  301.                         EmitStatement((AstStatement *) block -> Statement(si));
  302.                 }
  303.  
  304.                 if (! unit_type -> block_initializer_method)
  305.                 {
  306.                     int fi = 0,
  307.                         bi = 0;
  308.                     while (fi < initialized_instance_fields.Length() && bi < class_body -> NumBlocks())
  309.                     {
  310.                         if (initialized_instance_fields[fi] -> LeftToken() < class_body -> Block(bi) -> left_brace_token)
  311.                             InitializeInstanceVariable(initialized_instance_fields[fi++]);
  312.                         else
  313.                         {
  314.                             AstBlock *block = class_body -> Block(bi++);
  315.                             for (int si = 0; si < block -> NumStatements(); si++)
  316.                                 EmitStatement((AstStatement *) block -> Statement(si));
  317.                         }
  318.                     }
  319.  
  320.                     while (fi < initialized_instance_fields.Length())
  321.                         InitializeInstanceVariable(initialized_instance_fields[fi++]);
  322.  
  323.                     //
  324.                     // compile any initialization blocks
  325.                     //
  326.                     while (bi < class_body -> NumBlocks())
  327.                     {
  328.                         AstBlock *block = class_body -> Block(bi++);
  329.                         for (int si = 0; si < block -> NumStatements(); si++)
  330.                             EmitStatement((AstStatement *) block -> Statement(si));
  331.                     }
  332.                 }
  333.                 else
  334.                 {
  335.                     //
  336.                     // generate a call to the parameterless function block_initializer_function
  337.                     //
  338.                     PutOp(OP_ALOAD_0); // load address of object on which method is to be invoked
  339.                     PutOp(OP_INVOKENONVIRTUAL);
  340.                     CompleteCall(unit_type -> block_initializer_method, 0);
  341.                 }
  342.             }
  343.  
  344.             EmitStatement(constructor_block -> original_constructor_invocation);
  345.             PutOp(OP_RETURN);
  346.             EndMethod(method_index, this_constructor_symbol);
  347.  
  348.             //
  349.             // compile method associated with generated constructor
  350.             //
  351.             MethodSymbol *local_constructor_symbol = this_constructor_symbol -> LocalConstructor();
  352.             method_index = methods.NextIndex(); // index for method
  353.             BeginMethod(method_index, local_constructor_symbol);  // is constructor
  354.  
  355.             EmitStatement(constructor_block -> block);
  356.  
  357.             EndMethod(method_index, local_constructor_symbol);
  358.         }
  359.     }
  360.  
  361.     //
  362.     // If we need to generate a static initializer...
  363.     //
  364.     if (unit_type -> static_initializer_method)
  365.     {
  366.         assert(class_body -> NumStaticInitializers() > 0 || initialized_static_fields.Length() > 0);
  367.  
  368.         int method_index = methods.NextIndex(); // index for method
  369.         BeginMethod(method_index, unit_type -> static_initializer_method);
  370.  
  371.         //
  372.         // revisit members that are part of class initialization
  373.         //
  374.         int fi = 0,
  375.             bi = 0;
  376.         while (fi < class_body -> NumStaticInitializers() && bi < initialized_static_fields.Length())
  377.         {
  378.             if (class_body -> StaticInitializer(fi) -> static_token < initialized_static_fields[bi] -> LeftToken())
  379.                  EmitStatement(class_body -> StaticInitializer(fi++) -> block);
  380.             else InitializeClassVariable(initialized_static_fields[bi++]);
  381.         }
  382.  
  383.         while (fi < class_body -> NumStaticInitializers())
  384.             EmitStatement(class_body -> StaticInitializer(fi++) -> block);
  385.  
  386.         while (bi < initialized_static_fields.Length())
  387.             InitializeClassVariable(initialized_static_fields[bi++]);
  388.  
  389.         PutOp(OP_RETURN);
  390.         EndMethod(method_index, unit_type -> static_initializer_method);
  391.     }
  392.     else assert(class_body -> NumStaticInitializers() == 0 && initialized_static_fields.Length() == 0);
  393.  
  394.     FinishCode(unit_type);
  395.  
  396.     if (constant_pool.Length() > 65535)
  397.     {
  398.          this_semantic.ReportSemError(SemanticError::CONSTANT_POOL_OVERFLOW,
  399.                                       unit_type -> declaration -> LeftToken(),
  400.                                       unit_type -> declaration -> RightToken(),
  401.                                       unit_type -> ContainingPackage() -> PackageName(),
  402.                                       unit_type -> ExternalName());
  403.     }
  404.  
  405.     if (interfaces.Length() > 65535)
  406.     {
  407.          AstClassDeclaration *class_declaration = unit_type -> declaration -> ClassDeclarationCast();
  408.          AstInterfaceDeclaration *interface_declaration = unit_type -> declaration -> InterfaceDeclarationCast();
  409.          int n = (class_declaration ? class_declaration -> NumInterfaces()
  410.                                     : interface_declaration -> NumInterfaceMemberDeclarations());
  411.          Ast *left = (class_declaration ? class_declaration -> Interface(0)
  412.                                         : interface_declaration -> InterfaceMemberDeclaration(0)),
  413.              *right = (class_declaration ? class_declaration -> Interface(n - 1)
  414.                                          : interface_declaration -> InterfaceMemberDeclaration(n - 1));
  415.  
  416.          this_semantic.ReportSemError(SemanticError::INTERFACES_OVERFLOW,
  417.                                       left -> LeftToken(),
  418.                                       right -> RightToken(),
  419.                                       unit_type -> ContainingPackage() -> PackageName(),
  420.                                       unit_type -> ExternalName());
  421.     }
  422.  
  423.     if (fields.Length() > 65535)
  424.     {
  425.          this_semantic.ReportSemError(SemanticError::FIELDS_OVERFLOW,
  426.                                       unit_type -> declaration -> LeftToken(),
  427.                                       unit_type -> declaration -> RightToken(),
  428.                                       unit_type -> ContainingPackage() -> PackageName(),
  429.                                       unit_type -> ExternalName());
  430.     }
  431.  
  432.     if (methods.Length() > 65535)
  433.     {
  434.          this_semantic.ReportSemError(SemanticError::METHODS_OVERFLOW,
  435.                                       unit_type -> declaration -> LeftToken(),
  436.                                       unit_type -> declaration -> RightToken(),
  437.                                       unit_type -> ContainingPackage() -> PackageName(),
  438.                                       unit_type -> ExternalName());
  439.     }
  440.  
  441.     if (string_overflow)
  442.     {
  443.          this_semantic.ReportSemError(SemanticError::STRING_OVERFLOW,
  444.                                       unit_type -> declaration -> LeftToken(),
  445.                                       unit_type -> declaration -> RightToken(),
  446.                                       unit_type -> ContainingPackage() -> PackageName(),
  447.                                       unit_type -> ExternalName());
  448.     }
  449.  
  450.     if (library_method_not_found)
  451.     {
  452.          this_semantic.ReportSemError(SemanticError::LIBRARY_METHOD_NOT_FOUND,
  453.                                       unit_type -> declaration -> LeftToken(),
  454.                                       unit_type -> declaration -> RightToken(),
  455.                                       unit_type -> ContainingPackage() -> PackageName(),
  456.                                       unit_type -> ExternalName());
  457.     }
  458.  
  459.     if (this_semantic.NumErrors() == 0)
  460.          Write();
  461. #ifdef TEST
  462.     else if (this_control.option.debug_dump_class)
  463.          PrintCode();
  464. #endif
  465. }
  466.  
  467.  
  468. void ByteCode::CompileInterface()
  469. {
  470.     AstInterfaceDeclaration *interface_decl = unit_type -> declaration -> InterfaceDeclarationCast();
  471.  
  472.     Tuple<AstVariableDeclarator *> initialized_fields(unit_type -> NumVariableSymbols()); // fields needing code to initialize
  473.     {
  474.         for (int i = 0; i < interface_decl -> NumClassVariables(); i++)
  475.         {
  476.             AstFieldDeclaration *field_decl = interface_decl -> ClassVariable(i);
  477.  
  478.             for (int vi = 0; vi < field_decl -> NumVariableDeclarators(); vi++)
  479.             {
  480.                 AstVariableDeclarator *variable_declarator = field_decl -> VariableDeclarator(vi);
  481.                 VariableSymbol *vsym = variable_declarator -> symbol;
  482.  
  483.                 //
  484.                 // We need a static constructor-initializer if we encounter at least one
  485.                 // variable (all variable declared in an interface are implicitly static)
  486.                 // that is declared with an initialization expression that is not a
  487.                 // constant expression.
  488.                 //
  489.                 if (variable_declarator -> variable_initializer_opt)
  490.                 {
  491.                     AstExpression *init = variable_declarator -> variable_initializer_opt -> ExpressionCast();
  492.                     if (! (init && init -> IsConstant()))
  493.                         initialized_fields.Next() = variable_declarator;
  494.                 }
  495.  
  496.                 DeclareField(vsym);
  497.             }
  498.         }
  499.     }
  500.  
  501.     //
  502.     // Process all method members
  503.     //
  504.     {
  505.         for (int i = 0; i < interface_decl -> NumMethods(); i++)
  506.         {
  507.             AstMethodDeclaration *method = interface_decl -> Method(i);
  508.             if (method -> method_symbol)
  509.             {
  510.                 int method_index = methods.NextIndex();
  511.  
  512.                 BeginMethod(method_index, method -> method_symbol);
  513.                 EndMethod(method_index, method -> method_symbol);
  514.             }
  515.         }
  516.     }
  517.  
  518.     //
  519.     // If this interface contained field with initial value
  520.     //
  521.     if (unit_type -> static_initializer_method)
  522.     {
  523.         assert(initialized_fields.Length() > 0);
  524.  
  525.         int method_index = methods.NextIndex(); // index for method
  526.         BeginMethod(method_index, unit_type -> static_initializer_method);
  527.  
  528.         for (int i = 0; i < initialized_fields.Length(); i++)
  529.             InitializeClassVariable(initialized_fields[i]);
  530.  
  531.         PutOp(OP_RETURN);
  532.         EndMethod(method_index, unit_type -> static_initializer_method);
  533.     }
  534.     else assert(initialized_fields.Length() == 0);
  535.  
  536.     FinishCode(unit_type);
  537.  
  538.     if (constant_pool.Length() > 65535)
  539.     {
  540.          this_semantic.ReportSemError(SemanticError::CONSTANT_POOL_OVERFLOW,
  541.                                       unit_type -> declaration -> LeftToken(),
  542.                                       unit_type -> declaration -> RightToken(),
  543.                                       unit_type -> ContainingPackage() -> PackageName(),
  544.                                       unit_type -> ExternalName());
  545.     }
  546.  
  547.     if (this_semantic.NumErrors() == 0)
  548.          Write();
  549. #ifdef TEST
  550.     else if (this_control.option.debug_dump_class)
  551.          PrintCode();
  552. #endif
  553.  
  554.     return;
  555. }
  556.  
  557.  
  558. //
  559. // initialized_fields is a list of fields needing code to initialize.
  560. //
  561. void ByteCode::CompileConstructor(AstConstructorDeclaration *constructor, Tuple<AstVariableDeclarator *> &initialized_fields)
  562. {
  563.     MethodSymbol *method_symbol = constructor -> constructor_symbol;
  564.     TypeSymbol *type = method_symbol -> containing_type;
  565.     AstClassDeclaration *class_decl = type -> declaration -> ClassDeclarationCast();
  566.     AstClassBody *class_body = (class_decl ? class_decl -> class_body
  567.                                            : ((AstClassInstanceCreationExpression *) type -> declaration) -> class_body_opt);
  568.  
  569.     int method_index = methods.NextIndex(); // index for method
  570.     BeginMethod(method_index, method_symbol);
  571.  
  572.     AstConstructorBlock *constructor_block = constructor -> constructor_body -> ConstructorBlockCast();
  573.     if (constructor_block -> explicit_constructor_invocation_opt)
  574.         EmitStatement((AstStatement *) constructor_block -> explicit_constructor_invocation_opt);
  575.     else
  576.     {
  577.         assert(unit_type == this_control.Object() && "A constructor block without an explicit constructor_invocation");
  578.     }
  579.  
  580.     // supply needed field initialization unless constructor
  581.     // starts with explicit 'this' call to another constructor
  582.     if (! (constructor_block -> explicit_constructor_invocation_opt &&
  583.            constructor_block -> explicit_constructor_invocation_opt -> ThisCallCast()))
  584.     {
  585.         if (type -> NumEnclosingInstances())
  586.         {
  587.             VariableSymbol *this0_parameter = type -> EnclosingInstance(0);
  588.             PutOp(OP_ALOAD_0); // load address of object on which method is to be invoked
  589.             LoadLocal(1, this0_parameter -> Type());
  590.             PutOp(OP_PUTFIELD);
  591.             PutU2(RegisterFieldref(this0_parameter));
  592.         }
  593.  
  594.         if (class_body -> this_block) // compile explicit 'this' call if present
  595.         {
  596.             AstBlock *block = class_body -> this_block;
  597.             for (int si = 0; si < block -> NumStatements(); si++)
  598.                 EmitStatement((AstStatement *) block -> Statement(si));
  599.         }
  600.  
  601.         if (! type -> block_initializer_method)
  602.         {
  603.             int fi = 0,
  604.                 bi = 0;
  605.  
  606.             while (fi < initialized_fields.Length() && bi < class_body -> NumBlocks())
  607.             {
  608.                 if (initialized_fields[fi] -> LeftToken() < class_body -> Block(bi) -> left_brace_token)
  609.                     InitializeInstanceVariable(initialized_fields[fi++]);
  610.                 else
  611.                 {
  612.                     AstBlock *block = class_body -> Block(bi++);
  613.                     for (int si = 0; si < block -> NumStatements(); si++)
  614.                         EmitStatement((AstStatement *) block -> Statement(si));
  615.                 }
  616.             }
  617.  
  618.             while (fi < initialized_fields.Length())
  619.                 InitializeInstanceVariable(initialized_fields[fi++]);
  620.  
  621.             // compile any initialization blocks
  622.             while (bi < class_body -> NumBlocks())
  623.             {
  624.                 AstBlock *block = class_body -> Block(bi++);
  625.                 for (int si = 0; si < block -> NumStatements(); si++)
  626.                     EmitStatement((AstStatement *) block -> Statement(si));
  627.             }
  628.         }
  629.         else // generate a call to the parameterless function block_initializer_function
  630.         {
  631.             PutOp(OP_ALOAD_0); // load address of object on which method is to be invoked
  632.             PutOp(OP_INVOKENONVIRTUAL);
  633.             CompleteCall(type -> block_initializer_method, 0);
  634.         }
  635.     }
  636.  
  637.     EmitStatement(constructor_block -> block);
  638.  
  639.     EndMethod(method_index, method_symbol);
  640.  
  641.     return;
  642. }
  643.  
  644.  
  645. void ByteCode::DeclareField(VariableSymbol *symbol)
  646. {
  647.     int field_index = fields.NextIndex(); // index for field
  648.  
  649.     fields[field_index].SetFlags(symbol -> Flags());
  650.     fields[field_index].SetNameIndex(RegisterUtf8(symbol -> ExternalIdentity() -> Utf8_literal));
  651.     fields[field_index].SetDescriptorIndex(RegisterUtf8(symbol -> Type() -> signature));
  652.  
  653.     AstVariableDeclarator *variable_declarator = symbol -> declarator;
  654.     if (variable_declarator && symbol -> ACC_STATIC()) // a declared static variable (not a generated one!)
  655.     {
  656.         AstExpression *init = (variable_declarator -> variable_initializer_opt
  657.                                                     ? variable_declarator -> variable_initializer_opt -> ExpressionCast()
  658.                                                     : (AstExpression *) NULL);
  659.         LiteralValue *initial_value = (init ? init -> value : (LiteralValue *) NULL);
  660.  
  661.         TypeSymbol *type = symbol -> Type();
  662.         if (initial_value && (type -> Primitive() || (type == this_control.String() && initial_value != this_control.NullValue())))
  663.         {
  664.             //
  665.             // TODO: there seems to be a contradiction between the language spec and the VM spec.
  666.             // The language spec seems to require that a variable be initialized (in the class file)
  667.             // with a "ConstantValue" only if it is static. The VM spec, on the other hand, states
  668.             // that a static need not be final to be initialized with a ConstantValue.
  669.             // As of now, we are following the language spec - ergo, this extra test.
  670.             //
  671.             if (symbol -> ACC_FINAL())
  672.             {
  673.                 u2 index = (this_control.IsSimpleIntegerValueType(type) || type == this_control.boolean_type
  674.                                 ? RegisterInteger((IntLiteralValue *) initial_value)
  675.                                 : type == this_control.String()
  676.                                         ? RegisterString((Utf8LiteralValue *) initial_value)
  677.                                         : type == this_control.float_type
  678.                                                 ? RegisterFloat((FloatLiteralValue *) initial_value)
  679.                                                 : type == this_control.long_type
  680.                                                         ? RegisterLong((LongLiteralValue *) initial_value)
  681.                                                         : RegisterDouble((DoubleLiteralValue *) initial_value));
  682.                 u2 attribute_index = RegisterUtf8(this_control.ConstantValue_literal);
  683.                 fields[field_index].AddAttribute(new ConstantValue_attribute(attribute_index, index));
  684.             }
  685.         }
  686.     }
  687.  
  688.     if (symbol -> IsSynthetic())
  689.         fields[field_index].AddAttribute(CreateSyntheticAttribute());
  690.  
  691.     if (symbol -> IsDeprecated())
  692.         fields[field_index].AddAttribute(CreateDeprecatedAttribute());
  693.  
  694.     return;
  695. }
  696.  
  697.  
  698. //
  699. // Generate code for access method to private member of containing class
  700. //
  701. void ByteCode::GenerateAccessMethod(MethodSymbol *method_symbol)
  702. {
  703.     assert(method_symbol -> ACC_STATIC());
  704.  
  705.     int stack_words = 0,
  706.         argument_offset = 0; // offset to start of argument
  707.  
  708.     //
  709.     // Load the parameters
  710.     //
  711.     for (int i = 0; i < method_symbol -> NumFormalParameters(); i++)
  712.     {
  713.         TypeSymbol *local_type = method_symbol -> FormalParameter(i) -> Type();
  714.         stack_words += GetTypeWords(local_type);
  715.         LoadLocal(argument_offset, local_type);
  716.         argument_offset += GetTypeWords(local_type); // update position in stack
  717.     }
  718.  
  719.     MethodSymbol *method_sym = method_symbol -> accessed_member -> MethodCast();
  720.     if (method_sym)
  721.     {
  722.         PutOp(method_sym -> ACC_STATIC() ? OP_INVOKESTATIC : OP_INVOKENONVIRTUAL);
  723.         CompleteCall(method_sym, stack_words);
  724.     }
  725.     else
  726.     {
  727.         VariableSymbol *field_sym = method_symbol -> accessed_member -> VariableCast();
  728.  
  729.         if (method_symbol -> Type() == this_control.void_type) // writing to a field
  730.         {
  731.             TypeSymbol *parameter_type = method_symbol -> FormalParameter(field_sym -> ACC_STATIC() ? 0 : 1) -> Type();
  732.             PutOp(field_sym -> ACC_STATIC() ? OP_PUTSTATIC : OP_PUTFIELD);
  733.             PutU2(RegisterFieldref(field_sym));
  734.             ChangeStack(this_control.IsDoubleWordType(parameter_type) ? -2 : -1);
  735.         }
  736.         else // reading a field: need method to retrieve value of field
  737.         {
  738.             PutOp(field_sym -> ACC_STATIC() ? OP_GETSTATIC : OP_GETFIELD);
  739.             PutU2(RegisterFieldref(field_sym));
  740.             ChangeStack(this_control.IsDoubleWordType(method_symbol -> Type()) ? 2 : 1);
  741.         }
  742.     }
  743.  
  744.     //
  745.     // Method returns void, generate code for expression-less return statement.
  746.     // Otherwise, call GenerateReturn to generate proper code.
  747.     //
  748.     if (method_symbol -> Type() == this_control.void_type)
  749.          PutOp(OP_RETURN);
  750.     else GenerateReturn(method_symbol -> Type());
  751.  
  752.     //
  753.     // here to emit noop if would otherwise EmitBranch past end
  754.     //
  755.     if (last_label_pc >= code_attribute -> CodeLength())
  756.         PutNop(0);
  757.  
  758.     return;
  759. }
  760.  
  761.  
  762. void ByteCode::BeginMethod(int method_index, MethodSymbol *msym)
  763. {
  764.     assert(msym);
  765.  
  766. #ifdef DUMP
  767. if (this_control.option.g)
  768. {
  769. Coutput << "(51) Generating code for method \"" << msym -> Name()
  770.         << "\" in " << unit_type -> ContainingPackage() -> PackageName() << "/"
  771.         << unit_type -> ExternalName() << "\n";
  772. Coutput.flush();
  773. }
  774. #endif
  775.     MethodInitialization();
  776.  
  777.     methods[method_index].SetNameIndex(RegisterUtf8(msym -> ExternalIdentity() -> Utf8_literal));
  778.     methods[method_index].SetDescriptorIndex(RegisterUtf8(msym -> signature));
  779.     methods[method_index].SetFlags(msym -> Flags());
  780.  
  781.     if (msym -> IsSynthetic())
  782.         methods[method_index].AddAttribute(CreateSyntheticAttribute());
  783.  
  784.     if (msym -> IsDeprecated())
  785.         methods[method_index].AddAttribute(CreateDeprecatedAttribute());
  786.  
  787.     //
  788.     // Generate throws attribute if method throws any exceptions
  789.     //
  790.     if (msym -> NumThrows())
  791.     {
  792.         Exceptions_attribute *exceptions_attribute = new Exceptions_attribute(RegisterUtf8(this_control.Exceptions_literal));
  793.         for (int i = 0; i < msym -> NumThrows(); i++)
  794.             exceptions_attribute -> AddExceptionIndex(RegisterClass(msym -> Throws(i) -> fully_qualified_name));
  795.         methods[method_index].AddAttribute(exceptions_attribute);
  796.     }
  797.  
  798.     //
  799.     // If the method is contained in an interface and it is not a generated static initializer,
  800.     // no further processing ins needed
  801.     //
  802.     if (msym -> containing_type -> ACC_INTERFACE() && msym -> Identity() != this_control.clinit_name_symbol)
  803.         return;
  804.  
  805.     //
  806.     // here if need code and associated attributes.
  807.     //
  808.     if (! (msym -> ACC_ABSTRACT() || msym -> ACC_NATIVE()))
  809.     {
  810.         method_stack = new MethodStack(msym -> max_block_depth, msym -> block_symbol -> max_variable_index);
  811.  
  812.         code_attribute = new Code_attribute(RegisterUtf8(this_control.Code_literal), msym -> block_symbol -> max_variable_index);
  813.  
  814.         line_number = 0;
  815.         line_number_table_attribute = new LineNumberTable_attribute(RegisterUtf8(this_control.LineNumberTable_literal));
  816.  
  817.         local_variable_table_attribute = (this_control.option.g
  818.                                             ? new LocalVariableTable_attribute(RegisterUtf8(this_control.LocalVariableTable_literal))
  819.                                             : (LocalVariableTable_attribute *) NULL);
  820.     }
  821.  
  822.     VariableSymbol *last_parameter = (msym -> NumFormalParameters() ? msym -> FormalParameter(msym -> NumFormalParameters() - 1)
  823.                                                                     : (VariableSymbol *) NULL);
  824.  
  825.     last_parameter_index = (last_parameter ? last_parameter -> LocalVariableIndex() : -1);
  826.  
  827.     int num_parameter_slots = (last_parameter && this_control.IsDoubleWordType(last_parameter -> Type())
  828.                                                ? last_parameter_index + 1
  829.                                                : last_parameter_index);
  830.     if (num_parameter_slots > 255)
  831.     {
  832.         assert(msym -> method_or_constructor_declaration);
  833.  
  834.         AstMethodDeclaration *method_declaration = msym -> method_or_constructor_declaration -> MethodDeclarationCast();
  835.         AstConstructorDeclaration *constructor_declaration = msym -> method_or_constructor_declaration -> ConstructorDeclarationCast();
  836.         AstMethodDeclarator *declarator = (method_declaration ? method_declaration -> method_declarator
  837.                                                               : constructor_declaration -> constructor_declarator);
  838.  
  839.         this_semantic.ReportSemError(SemanticError::PARAMETER_OVERFLOW,
  840.                                      declarator -> left_parenthesis_token,
  841.                                      declarator -> right_parenthesis_token,
  842.                                      msym -> Header(),
  843.                                      unit_type -> ContainingPackage() -> PackageName(),
  844.                                      unit_type -> ExternalName());
  845.     }
  846.  
  847.     return;
  848. }
  849.  
  850.  
  851. void ByteCode::EndMethod(int method_index, MethodSymbol *msym)
  852. {
  853.     assert(msym);
  854.  
  855.     if (! (msym -> ACC_ABSTRACT() || msym -> ACC_NATIVE()))
  856.     {
  857.         //
  858.         // Make sure that no component in the code attribute exceeded its limit.
  859.         //
  860.         if (msym -> block_symbol -> max_variable_index > 65535)
  861.         {
  862.             this_semantic.ReportSemError(SemanticError::LOCAL_VARIABLES_OVERFLOW,
  863.                                          msym -> method_or_constructor_declaration -> LeftToken(),
  864.                                          msym -> method_or_constructor_declaration -> RightToken(),
  865.                                          msym -> Header(),
  866.                                          unit_type -> ContainingPackage() -> PackageName(),
  867.                                          unit_type -> ExternalName());
  868.         }
  869.  
  870.         if (max_stack > 65535)
  871.         {
  872.             this_semantic.ReportSemError(SemanticError::STACK_OVERFLOW,
  873.                                          msym -> method_or_constructor_declaration -> LeftToken(),
  874.                                          msym -> method_or_constructor_declaration -> RightToken(),
  875.                                          msym -> Header(),
  876.                                          unit_type -> ContainingPackage() -> PackageName(),
  877.                                          unit_type -> ExternalName());
  878.         }
  879.  
  880.         if (code_attribute -> CodeLength() > 65535)
  881.         {
  882.             this_semantic.ReportSemError(SemanticError::CODE_OVERFLOW,
  883.                                          msym -> method_or_constructor_declaration -> LeftToken(),
  884.                                          msym -> method_or_constructor_declaration -> RightToken(),
  885.                                          msym -> Header(),
  886.                                          unit_type -> ContainingPackage() -> PackageName(),
  887.                                          unit_type -> ExternalName());
  888.         }
  889.  
  890.         //
  891.         //
  892.         //
  893.         code_attribute -> SetMaxStack(max_stack);
  894.  
  895.         if (last_label_pc >= code_attribute -> CodeLength()) // here to emit noop if would otherwise branch past end
  896.             PutNop(0);
  897.  
  898.         //
  899.         // attribute length:
  900.         // need to review how to make attribute_name and attribute_length
  901.         // only write line number attribute if -O not specified and there
  902.         // are line numbers to write.
  903.         //
  904.         if ((! this_control.option.O) && line_number_table_attribute -> LineNumberTableLength() > 0)
  905.              code_attribute -> AddAttribute(line_number_table_attribute);
  906.         else delete line_number_table_attribute; // line_number_table_attribute not needed, so delete it now
  907.  
  908.         //
  909.         // debug & not dealing with generated accessed method
  910.         //
  911.         if (this_control.option.g && (! msym -> accessed_member) && (msym -> Identity() != this_control.class_name_symbol))
  912.         {
  913.             if (! msym -> ACC_STATIC()) // add 'this' to local variable table
  914.             {
  915.                 local_variable_table_attribute -> AddLocalVariable(0,
  916.                                                                    code_attribute -> CodeLength(),
  917.                                                                    RegisterUtf8(this_control.this_literal),
  918.                                                                    RegisterUtf8(msym -> containing_type -> signature),
  919.                                                                    0);
  920.             }
  921.  
  922.             //
  923.             // For a normal constructor or method.
  924.             //
  925.             for (int i = 0; i < msym -> NumFormalParameters(); i++)
  926.             {
  927.                 VariableSymbol *parameter = msym -> FormalParameter(i);
  928.                 local_variable_table_attribute -> AddLocalVariable(0,
  929.                                                                    code_attribute -> CodeLength(),
  930.                                                                    RegisterUtf8(parameter -> ExternalIdentity() -> Utf8_literal),
  931.                                                                    RegisterUtf8(parameter -> Type() -> signature),
  932.                                                                    parameter -> LocalVariableIndex());
  933.             }
  934.  
  935.             if (local_variable_table_attribute -> LocalVariableTableLength() > 0)
  936.                  code_attribute -> AddAttribute(local_variable_table_attribute);
  937.             else delete local_variable_table_attribute; // local_variable_table_attribute not needed, so delete it now
  938.         }
  939.  
  940.         methods[method_index].AddAttribute(code_attribute);
  941.  
  942.         delete method_stack;
  943.     }
  944.  
  945.     return;
  946. }
  947.  
  948.  
  949. void ByteCode::InitializeClassVariable(AstVariableDeclarator *vd)
  950. {
  951.     assert(vd -> variable_initializer_opt);
  952.  
  953.     AstExpression *expression = vd -> variable_initializer_opt -> ExpressionCast();
  954.     if (expression)
  955.     {
  956.         //
  957.         // TODO: there seems to be a contradiction between the language spec and the VM spec.
  958.         // The language spec seems to require that a variable be initialized (in the class file)
  959.         // with a "ConstantValue" only if it is static. The VM spec, on the other hand, states
  960.         // that a static need not be final to be initialized with a ConstantValue.
  961.         // As of now, we are following the language spec - ergo, this extra test.
  962.         //
  963.         // if (expression -> IsConstant())  // if already initialized
  964.         //
  965.         assert(vd -> symbol);
  966.  
  967.         if (expression -> IsConstant() && vd -> symbol -> ACC_FINAL())  // if already initialized
  968.             return;
  969.         EmitExpression(expression);
  970.     }
  971.     else
  972.     {
  973.         AstArrayInitializer *array_initializer = vd -> variable_initializer_opt -> ArrayInitializerCast();
  974.  
  975.         assert(array_initializer);
  976.  
  977.         InitializeArray(vd -> symbol -> Type(), array_initializer);
  978.     }
  979.  
  980.     PutOp(OP_PUTSTATIC);
  981.     ChangeStack(expression && this_control.IsDoubleWordType(expression -> Type()) ? -2 : -1);
  982.     PutU2(RegisterFieldref(vd -> symbol));
  983.  
  984.     return;
  985. }
  986.  
  987.  
  988. void ByteCode::InitializeInstanceVariable(AstVariableDeclarator *vd)
  989. {
  990.     assert(vd -> variable_initializer_opt); // field needs initialization
  991.  
  992.     AstExpression *expression = vd -> variable_initializer_opt -> ExpressionCast();
  993.     if (expression)
  994.     {
  995.         PutOp(OP_ALOAD_0); // load 'this'
  996.         EmitExpression(expression);
  997.     }
  998.     else
  999.     {
  1000.         AstArrayInitializer *array_initializer = vd -> variable_initializer_opt -> ArrayInitializerCast();
  1001.  
  1002.         assert(array_initializer);
  1003.  
  1004.         PutOp(OP_ALOAD_0); // load 'this'
  1005.         InitializeArray(vd -> symbol -> Type(), array_initializer);
  1006.     }
  1007.  
  1008.     PutOp(OP_PUTFIELD);
  1009.     ChangeStack(expression && this_control.IsDoubleWordType(expression -> Type()) ? -2 : -1);
  1010.     PutU2(RegisterFieldref(vd -> symbol));
  1011.  
  1012.     return;
  1013. }
  1014.  
  1015.  
  1016. void ByteCode::InitializeArray(TypeSymbol *type, AstArrayInitializer *array_initializer)
  1017. {
  1018.     TypeSymbol *subtype = type -> ArraySubtype();
  1019.  
  1020.     LoadImmediateInteger(array_initializer -> NumVariableInitializers());
  1021.     EmitNewArray(1, type); // make the array
  1022.     for (int i = 0; i < array_initializer -> NumVariableInitializers(); i++)
  1023.     {
  1024.         Ast *entry = array_initializer -> VariableInitializer(i);
  1025.         PutOp(OP_DUP);
  1026.         LoadImmediateInteger(i);
  1027.         AstExpression *expr = entry -> ExpressionCast();
  1028.         if (expr)
  1029.              EmitExpression(expr);
  1030.         else
  1031.         {
  1032.             assert(entry -> ArrayInitializerCast());
  1033.  
  1034.             InitializeArray(subtype, entry -> ArrayInitializerCast());
  1035.         }
  1036.  
  1037.         StoreArrayElement(subtype);
  1038.     }
  1039.  
  1040.     return;
  1041. }
  1042.  
  1043.  
  1044. //
  1045. // Generate code for local variable declaration.
  1046. //
  1047. void ByteCode::DeclareLocalVariable(AstVariableDeclarator *declarator)
  1048. {
  1049.     if (declarator -> symbol -> initial_value)
  1050.         LoadLiteral(declarator -> symbol -> initial_value, declarator -> symbol -> Type());
  1051.     else if (declarator -> variable_initializer_opt)
  1052.     {
  1053.         AstArrayCreationExpression *ace = declarator -> variable_initializer_opt -> ArrayCreationExpressionCast();
  1054.         if (ace)
  1055.             (void) EmitArrayCreationExpression(ace);
  1056.         else if (declarator -> variable_initializer_opt -> ArrayInitializerCast())
  1057.             InitializeArray(declarator -> symbol -> Type(), declarator -> variable_initializer_opt -> ArrayInitializerCast());
  1058.         else // evaluation as expression
  1059.             EmitExpression(declarator -> variable_initializer_opt -> ExpressionCast());
  1060.     }
  1061.     else return; // if nothing to initialize
  1062.  
  1063.     StoreLocal(declarator -> symbol -> LocalVariableIndex(), declarator -> symbol -> Type());
  1064.  
  1065.     if (this_control.option.g)
  1066.     {
  1067. #ifdef TEST
  1068.         assert(method_stack -> StartPc(declarator -> symbol) == 0xFFFF); // must be uninitialized
  1069. #endif
  1070. #ifdef DUMP
  1071. Coutput << "(53) Variable \"" << declarator -> symbol -> Name()
  1072.         << "\" numbered " << declarator -> symbol -> LocalVariableIndex()
  1073.         << " was processed\n";
  1074. Coutput.flush();
  1075. #endif
  1076.         method_stack -> StartPc(declarator -> symbol) = code_attribute -> CodeLength();
  1077.     }
  1078.  
  1079.     return;
  1080. }
  1081.  
  1082.  
  1083. //
  1084. // JLS Chapter 13: Blocks and Statements
  1085. //  Statements control the sequence of evaluation of Java programs,
  1086. //  are executed for their effects and do not have values.
  1087. //
  1088. // Processing of loops requires a loop stack, especially to hangle
  1089. // break and continue statements.
  1090. // Loops have three labels, LABEL_BEGIN for start of loop body,
  1091. // LABEL_BREAK to leave the loop, and LABEL_CONTINUE to continue the iteration.
  1092. // Each loop requires a break label; other labels are defined and used
  1093. // as needed.
  1094. // Labels allocated but never used incur no extra cost in the generated
  1095. // byte code, only in additional execution expense during compilation.
  1096. //
  1097. void ByteCode::EmitStatement(AstStatement *statement)
  1098. {
  1099.     if (! statement -> BlockCast())
  1100.     {
  1101.         line_number_table_attribute -> AddLineNumber(code_attribute -> CodeLength(),
  1102.                                                      this_semantic.lex_stream -> Line(statement -> LeftToken()));
  1103.     }
  1104.  
  1105.     if (this_control.option.g)
  1106.     {
  1107.         for (int i = 0; i < statement -> NumDefinedVariables(); i++)
  1108.         {
  1109.             VariableSymbol *variable = statement -> DefinedVariable(i);
  1110. #ifdef TEST
  1111.             assert(method_stack -> StartPc(variable) == 0xFFFF); // must be uninitialized
  1112. #endif
  1113. #ifdef DUMP
  1114. Coutput << "(55) Variable \"" << variable -> Name()
  1115.         << "\" numbered " << variable -> LocalVariableIndex()
  1116.         << " was processed\n";
  1117. Coutput.flush();
  1118. #endif
  1119.             method_stack -> StartPc(variable) = code_attribute -> CodeLength();
  1120.         }
  1121.     }
  1122.  
  1123.     stack_depth = 0; // stack empty at start of statement
  1124.  
  1125.     switch (statement -> kind)
  1126.     {
  1127.         case Ast::BLOCK: // JLS 13.2
  1128.              EmitBlockStatement((AstBlock *) statement);
  1129.              break;
  1130.         case Ast::LOCAL_VARIABLE_DECLARATION: // JLS 13.3
  1131.              {
  1132.                  AstLocalVariableDeclarationStatement *lvds = statement -> LocalVariableDeclarationStatementCast();
  1133.                  for (int i = 0; i < lvds -> NumVariableDeclarators(); i++)
  1134.                      DeclareLocalVariable(lvds -> VariableDeclarator(i));
  1135.              }
  1136.              break;
  1137.         case Ast::EMPTY_STATEMENT: // JLS 13.5
  1138.              break;
  1139.         case Ast::EXPRESSION_STATEMENT: // JLS 13.7
  1140.              EmitStatementExpression(statement -> ExpressionStatementCast() -> expression);
  1141.              break;
  1142.         case Ast::IF: // JLS 13.8
  1143.              {
  1144.                  AstIfStatement *if_statement = (AstIfStatement *) statement;
  1145.                  if (if_statement -> expression -> IsConstant())
  1146.                  {
  1147.                      IntLiteralValue *if_constant_expr = (IntLiteralValue *) if_statement -> expression -> value;
  1148.  
  1149.                      if (if_constant_expr -> value)
  1150.                           EmitStatement(if_statement -> true_statement);
  1151.                      else if (if_statement -> false_statement_opt) // if there is false part
  1152.                           EmitStatement(if_statement -> false_statement_opt);
  1153.                  }
  1154.                  else if (if_statement -> false_statement_opt) // if true and false parts
  1155.                  {
  1156.                      Label label1,
  1157.                            label2;
  1158.                      EmitBranchIfExpression(if_statement -> expression, false, label1);
  1159.                      stack_depth = 0;
  1160.  
  1161.                      AstStatement *true_statement = if_statement -> true_statement;
  1162.                      EmitStatement(true_statement);
  1163.                      if (true_statement -> can_complete_normally)
  1164.                          EmitBranch(OP_GOTO, label2);
  1165.  
  1166.                      DefineLabel(label1);
  1167.                      EmitStatement(if_statement -> false_statement_opt);
  1168.  
  1169.                      if (true_statement -> can_complete_normally)
  1170.                          DefineLabel(label2);
  1171.  
  1172.                      CompleteLabel(label1);
  1173.                      CompleteLabel(label2);
  1174.                  }
  1175.                  else // if no false part
  1176.                  {
  1177.                      Label label1;
  1178.                      EmitBranchIfExpression(if_statement -> expression, false, label1);
  1179.                      stack_depth = 0;
  1180.                      EmitStatement(if_statement -> true_statement);
  1181.                      DefineLabel(label1);
  1182.                      CompleteLabel(label1);
  1183.                  }
  1184.              }
  1185.              break;
  1186.         case Ast::SWITCH: // JLS 13.9
  1187.              EmitSwitchStatement(statement -> SwitchStatementCast());
  1188.              break;
  1189.         case Ast::SWITCH_BLOCK: // JLS 13.9
  1190.         case Ast::CASE:
  1191.         case Ast::DEFAULT:
  1192.             //
  1193.             // These nodes are handled by SwitchStatement and
  1194.             // are not directly visited
  1195.             //
  1196.             break;
  1197.         case Ast::WHILE: // JLS 13.10
  1198.              {
  1199.                  AstWhileStatement *wp = statement -> WhileStatementCast();
  1200.                  //
  1201.                  // Branch to continuation test. This test is placed after the
  1202.                  // body of the loop we can fall through into it after each
  1203.                  // loop iteration without the need for an additional branch.
  1204.                  //
  1205.                  EmitBranch(OP_GOTO, method_stack -> TopContinueLabel());
  1206.                  Label begin_label;
  1207.                  DefineLabel(begin_label);
  1208.                  EmitStatement(wp -> statement);
  1209.                  DefineLabel(method_stack -> TopContinueLabel());
  1210.                  stack_depth = 0;
  1211.  
  1212.                  //
  1213.                  // Reset the line number before evaluating the expression
  1214.                  //
  1215.                  line_number_table_attribute -> AddLineNumber(code_attribute -> CodeLength(),
  1216.                                                               this_semantic.lex_stream -> Line(wp -> expression -> LeftToken()));
  1217.  
  1218.                  EmitBranchIfExpression(wp -> expression, true, begin_label);
  1219.                  CompleteLabel(begin_label);
  1220.                  CompleteLabel(method_stack -> TopContinueLabel());
  1221.              }
  1222.              break;
  1223.         case Ast::DO: // JLS 13.11
  1224.              {
  1225.                  AstDoStatement *sp = statement -> DoStatementCast();
  1226.                  Label begin_label;
  1227.                  DefineLabel(begin_label);
  1228.                  EmitStatement(sp -> statement);
  1229.                  DefineLabel(method_stack -> TopContinueLabel());
  1230.                  stack_depth = 0;
  1231.  
  1232.                  //
  1233.                  // Reset the line number before evaluating the expression
  1234.                  //
  1235.                  line_number_table_attribute -> AddLineNumber(code_attribute -> CodeLength(),
  1236.                                                               this_semantic.lex_stream -> Line(sp -> expression -> LeftToken()));
  1237.  
  1238.                  EmitBranchIfExpression(sp -> expression, true, begin_label);
  1239.                  CompleteLabel(begin_label);
  1240.                  CompleteLabel(method_stack -> TopContinueLabel());
  1241.              }
  1242.              break;
  1243.         case Ast::FOR: // JLS 13.12
  1244.              {
  1245.                  AstForStatement *for_statement = statement -> ForStatementCast();
  1246.                  for (int i = 0; i < for_statement -> NumForInitStatements(); i++)
  1247.                      EmitStatement(for_statement -> ForInitStatement(i));
  1248.                  Label begin_label,
  1249.                        test_label;
  1250.                  EmitBranch(OP_GOTO, test_label);
  1251.                  DefineLabel(begin_label);
  1252.                  EmitStatement(for_statement -> statement);
  1253.                  DefineLabel(method_stack -> TopContinueLabel());
  1254.                  for (int j = 0; j < for_statement -> NumForUpdateStatements(); j++)
  1255.                      EmitStatement(for_statement -> ForUpdateStatement(j));
  1256.                  DefineLabel(test_label);
  1257.  
  1258.                  AstExpression *end_expr = for_statement -> end_expression_opt;
  1259.                  if (end_expr)
  1260.                  {
  1261.                      stack_depth = 0;
  1262.  
  1263.                      //
  1264.                      // Reset the line number before evaluating the expression
  1265.                      //
  1266.                      line_number_table_attribute -> AddLineNumber(code_attribute -> CodeLength(),
  1267.                                                                   this_semantic.lex_stream -> Line(end_expr -> LeftToken()));
  1268.  
  1269.                      EmitBranchIfExpression(end_expr, true, begin_label);
  1270.                  }
  1271.                  else EmitBranch(OP_GOTO, begin_label);
  1272.  
  1273.                  CompleteLabel(begin_label);
  1274.                  CompleteLabel(test_label);
  1275.                  CompleteLabel(method_stack -> TopContinueLabel());
  1276.              }
  1277.              break;
  1278.         case Ast::BREAK: // JLS 13.13
  1279.              ProcessAbruptExit(statement -> BreakStatementCast() -> nesting_level);
  1280.              EmitBranch(OP_GOTO, method_stack -> BreakLabel(statement -> BreakStatementCast() -> nesting_level));
  1281.              break;
  1282.         case Ast::CONTINUE: // JLS 13.14
  1283.              ProcessAbruptExit(statement -> ContinueStatementCast() -> nesting_level);
  1284.              EmitBranch(OP_GOTO, method_stack -> ContinueLabel(statement -> ContinueStatementCast() -> nesting_level));
  1285.              break;
  1286.         case Ast::RETURN: // JLS 13.15
  1287.              EmitReturnStatement(statement -> ReturnStatementCast());
  1288.              break;
  1289.         case Ast::SUPER_CALL:
  1290.              EmitSuperInvocation((AstSuperCall *) statement);
  1291.              break;
  1292.         case Ast::THIS_CALL:
  1293.              EmitThisInvocation((AstThisCall *) statement);
  1294.              break;
  1295.         case Ast::THROW: // JLS 13.16
  1296.              EmitExpression(statement -> ThrowStatementCast() -> expression);
  1297.              PutOp(OP_ATHROW);
  1298.              break;
  1299.         case Ast::SYNCHRONIZED_STATEMENT: // JLS 13.17
  1300.              EmitSynchronizedStatement(statement -> SynchronizedStatementCast());
  1301.              break;
  1302.         case Ast::TRY: // JLS 13.18
  1303.              EmitTryStatement(statement -> TryStatementCast());
  1304.              break;
  1305.         case Ast::CLASS: // Class Declaration
  1306.         case Ast::INTERFACE: // InterfaceDeclaration
  1307.              //
  1308.              // these are factored out by the front end; and so must be skipped here
  1309.              //
  1310.              break;
  1311.         case Ast::CATCH:   // JLS 13.18
  1312.         case Ast::FINALLY: // JLS 13.18
  1313.              // handled by TryStatement
  1314.         default:
  1315.             assert(false && "unknown statement kind");
  1316.             break;
  1317.     }
  1318.  
  1319.     return;
  1320. }
  1321.  
  1322.  
  1323. void ByteCode::EmitReturnStatement(AstReturnStatement *statement)
  1324. {
  1325.     AstExpression *expression = statement -> expression_opt;
  1326.  
  1327.     if (! expression)
  1328.     {
  1329.         ProcessAbruptExit(method_stack -> NestingLevel(0));
  1330.         PutOp(OP_RETURN);
  1331.     }
  1332.     else
  1333.     {
  1334.         TypeSymbol *type = expression -> Type();
  1335.         assert(type != this_control.void_type);
  1336.  
  1337.         EmitExpression(expression);
  1338.  
  1339.         ProcessAbruptExit(method_stack -> NestingLevel(0), type);
  1340.  
  1341.         GenerateReturn(type);
  1342.     }
  1343.  
  1344.     return;
  1345. }
  1346.  
  1347.  
  1348. void ByteCode::EmitBlockStatement(AstBlock *block)
  1349. {
  1350.     stack_depth = 0; // stack empty at start of statement
  1351.  
  1352.     method_stack -> Push(block);
  1353.  
  1354.     for (int i = 0; i < block -> NumStatements(); i++)
  1355.         EmitStatement((AstStatement *) block -> Statement(i));
  1356.  
  1357.     //
  1358.     // Always define LABEL_BREAK at this point, and complete its definition.
  1359.     //
  1360.     if (IsLabelUsed(method_stack -> TopBreakLabel())) // need define only if used
  1361.         DefineLabel(method_stack -> TopBreakLabel());
  1362.     CompleteLabel(method_stack -> TopBreakLabel());
  1363.  
  1364.     if (this_control.option.g)
  1365.     {
  1366.         for (int i = 0; i < block -> NumLocallyDefinedVariables(); i++)
  1367.         {
  1368.             VariableSymbol *variable = block -> LocallyDefinedVariable(i);
  1369.  
  1370. #ifdef TEST
  1371.             assert(method_stack -> StartPc(variable) != 0xFFFF);
  1372. #endif
  1373. #ifdef DUMP
  1374. Coutput << "(56) The symbol \"" << variable -> Name()
  1375.         << "\" numbered " << variable -> LocalVariableIndex()
  1376.         << " was released\n";
  1377. Coutput.flush();
  1378. #endif
  1379.             local_variable_table_attribute -> AddLocalVariable(method_stack -> StartPc(variable),
  1380.                                                                code_attribute -> CodeLength(),
  1381.                                                                RegisterUtf8(variable -> ExternalIdentity() -> Utf8_literal),
  1382.                                                                RegisterUtf8(variable -> Type() -> signature),
  1383.                                                                variable -> LocalVariableIndex());
  1384.         }
  1385.     }
  1386.  
  1387.     method_stack -> Pop();
  1388.  
  1389.     return;
  1390. }
  1391.  
  1392.  
  1393. void ByteCode::EmitStatementExpression(AstExpression *expression)
  1394. {
  1395.     switch (expression -> kind)
  1396.     {
  1397.         case Ast::PARENTHESIZED_EXPRESSION:
  1398.              (void) EmitStatementExpression(expression -> ParenthesizedExpressionCast() -> expression);
  1399.              break;
  1400.         case Ast::CALL:
  1401.              {
  1402.                  AstMethodInvocation *method_call = (AstMethodInvocation *) expression;
  1403.                  EmitMethodInvocation(method_call);
  1404.                  if (method_call -> Type() != this_control.void_type)
  1405.                      PutOp(this_control.IsDoubleWordType(method_call -> Type()) ? OP_POP2 : OP_POP); // discard value
  1406.             }
  1407.             break;
  1408.         case Ast::POST_UNARY:
  1409.              (void) EmitPostUnaryExpression((AstPostUnaryExpression *) expression, false);
  1410.              break;
  1411.         case Ast::PRE_UNARY:
  1412.              (void) EmitPreUnaryExpression((AstPreUnaryExpression *) expression, false);
  1413.              break;
  1414.         case Ast::ASSIGNMENT:
  1415.              EmitAssignmentExpression((AstAssignmentExpression *) expression, false);
  1416.              break;
  1417.         case Ast::CLASS_CREATION:
  1418.              (void) EmitClassInstanceCreationExpression((AstClassInstanceCreationExpression *) expression, false);
  1419.              break;
  1420.         default:
  1421.              assert(false && "invalid statement expression kind");
  1422.     }
  1423. }
  1424.  
  1425.  
  1426. //
  1427. // Generate code for switch statement. Good code generation requires
  1428. // detailed knowledge of the target machine. Lacking this, we simply
  1429. // choose between LOOKUPSWITCH and TABLESWITCH by picking that
  1430. // opcode that takes the least number of bytes in the byte code.
  1431. //
  1432. //
  1433. // note that if using table, then must provide slot for every
  1434. // entry in the range low..high, even though the user may not
  1435. // have provided an explicit entry, in which case the default
  1436. // action is to be taken. For example
  1437. // switch (e) {
  1438. //  case 1:2:3: act1; break;
  1439. //  case 5:6:   act2; break;
  1440. //  default: defact; break;
  1441. // }
  1442. // translated as
  1443. // switch (e)
  1444. // switch (e) {
  1445. //  case 1:2:3: act1; break;
  1446. //  case 4: goto defa:
  1447. //  case 5:6:   act2; break;
  1448. //  defa:
  1449. //  default: defact;
  1450. // }
  1451. //
  1452. void ByteCode::EmitSwitchStatement(AstSwitchStatement *switch_statement)
  1453. {
  1454.     AstBlock *switch_block = switch_statement -> switch_block;
  1455.  
  1456.     stack_depth = 0; // stack empty at start of statement
  1457.  
  1458.     //
  1459.     // Use tableswitch if have exact match or size of tableswitch
  1460.     // case is no more than 30 bytes more code than lookup case
  1461.     //
  1462.     bool use_lookup = true; // set if using LOOKUPSWITCH opcode
  1463.     int ncases = switch_statement -> NumCases(),
  1464.         nlabels = ncases,
  1465.         high = 0,
  1466.         low = 0;
  1467.     if (ncases > 0)
  1468.     {
  1469.         low = switch_statement -> Case(0) -> Value();
  1470.         high = switch_statement -> Case(ncases - 1) -> Value();
  1471.  
  1472.         //
  1473.         // want to compute
  1474.         //  (2 + high-low + 1) < (1 + ncases * 2 + 30)
  1475.         // but must guard against overflow, so factor out
  1476.         //  high - low < ncases * 2 + 28
  1477.         // but can't have number of labels < number of cases
  1478.         //
  1479.         LongInt range = LongInt(high) - low + 1;
  1480.         if (range < (ncases * 2 + 28))
  1481.         {
  1482.             use_lookup = false; // use tableswitch
  1483.             nlabels = range.LowWord();
  1484.  
  1485.             assert(range.HighWord() == 0);
  1486.             assert(nlabels >= ncases);
  1487.         }
  1488.     }
  1489.  
  1490.     //
  1491.     // Reset the line number before evaluating the expression
  1492.     //
  1493.     line_number_table_attribute -> AddLineNumber(code_attribute -> CodeLength(),
  1494.                                                  this_semantic.lex_stream -> Line(switch_statement -> expression -> LeftToken()));
  1495.     EmitExpression(switch_statement -> expression);
  1496.  
  1497.     stack_depth = 0;
  1498.     PutOp(use_lookup ? OP_LOOKUPSWITCH : OP_TABLESWITCH);
  1499.     int op_start = last_op_pc; // pc at start of instruction
  1500.  
  1501.     //
  1502.     // supply any needed padding
  1503.     //
  1504.     while(code_attribute -> CodeLength() % 4 != 0)
  1505.         PutNop(0);
  1506.  
  1507.     //
  1508.     // Set up the environment for the switch block.
  1509.     //
  1510.     method_stack -> Push(switch_block);
  1511.  
  1512.     //
  1513.     // Note that if no default clause in switch statement, must allocate
  1514.     // one that corresponds to do nothing and branches to start of next
  1515.     // statement.
  1516.     //
  1517.     Label *case_labels = new Label[(use_lookup ? ncases : nlabels) + 1],
  1518.           default_label;
  1519.     UseLabel(switch_statement -> default_case.switch_block_statement ? default_label : method_stack -> TopBreakLabel(),
  1520.              4,
  1521.              code_attribute -> CodeLength() - op_start);
  1522.  
  1523.     //
  1524.     //
  1525.     //
  1526.     if (use_lookup)
  1527.     {
  1528.         PutU4(ncases);
  1529.  
  1530.         for (int i = 0; i < ncases; i++)
  1531.         {
  1532.             PutU4(switch_statement -> Case(i) -> Value());
  1533.             UseLabel(case_labels[switch_statement -> Case(i) -> index], 4, code_attribute -> CodeLength() - op_start);
  1534.         }
  1535.     }
  1536.     else
  1537.     {
  1538.         bool *has_tag = new bool[nlabels + 1];
  1539.  
  1540.         for (int i = 0; i < nlabels; i++)
  1541.             has_tag[i] = false;
  1542.  
  1543.         PutU4(low);
  1544.         PutU4(high);
  1545.  
  1546.         //
  1547.         // mark cases for which no case tag available, i.e., default cases
  1548.         //
  1549.         for (int j = 0; j < switch_block -> NumStatements(); j++)
  1550.         {
  1551.             AstSwitchBlockStatement *switch_block_statement = (AstSwitchBlockStatement *) switch_block -> Statement(j);
  1552.  
  1553.             //
  1554.             // process labels for this block
  1555.             //
  1556.             for (int li = 0; li < switch_block_statement -> NumSwitchLabels(); li++)
  1557.             {
  1558.                 AstCaseLabel *case_label = switch_block_statement -> SwitchLabel(li) -> CaseLabelCast();
  1559.                 if (case_label)
  1560.                 {
  1561.                     int label_index = switch_statement -> Case(case_label -> map_index) -> Value() - low;
  1562.                     has_tag[label_index] = true;
  1563.                 }
  1564.             }
  1565.         }
  1566.  
  1567.         //
  1568.         // Now emit labels in instruction, using appropriate index
  1569.         //
  1570.         for (int k = 0; k < nlabels; k++)
  1571.         {
  1572.             UseLabel(has_tag[k] ? case_labels[k]
  1573.                                 : switch_statement -> default_case.switch_block_statement
  1574.                                        ? default_label
  1575.                                        : method_stack -> TopBreakLabel(),
  1576.                      4,
  1577.                      code_attribute -> CodeLength() - op_start);
  1578.         }
  1579.  
  1580.         delete [] has_tag;
  1581.     }
  1582.  
  1583.     //
  1584.     // march through switch block statements, compiling blocks in
  1585.     // proper order. We must respect order in which blocks seen
  1586.     // so that blocks lacking a terminal break fall through to the
  1587.     // proper place.
  1588.     //
  1589.     for (int i = 0; i < switch_block -> NumStatements(); i++)
  1590.     {
  1591.         AstSwitchBlockStatement *switch_block_statement = (AstSwitchBlockStatement *) switch_block -> Statement(i);
  1592.  
  1593.         //
  1594.         // process labels for this block
  1595.         //
  1596.         for (int li = 0; li < switch_block_statement -> NumSwitchLabels(); li++)
  1597.         {
  1598.             AstCaseLabel *case_label = switch_block_statement -> SwitchLabel(li) -> CaseLabelCast();
  1599.             if (case_label)
  1600.             {
  1601.                 int map_index = case_label -> map_index;
  1602.  
  1603.                 if (use_lookup)
  1604.                     DefineLabel(case_labels[map_index]);
  1605.                 else
  1606.                 {
  1607.                     //
  1608.                     // TODO: Do this more efficiently ??? !!!
  1609.                     //
  1610.                     for (int di = 0; di < switch_statement -> NumCases(); di++)
  1611.                     {
  1612.                         if (switch_statement -> Case(di) -> index == map_index)
  1613.                         {
  1614.                             int ci = switch_statement -> Case(di) -> Value() - low;
  1615.                             DefineLabel(case_labels[ci]);
  1616.                             break;
  1617.                         }
  1618.                     }
  1619.                 }
  1620.             }
  1621.             else
  1622.             {
  1623.                 assert(switch_block_statement -> SwitchLabel(li) -> DefaultLabelCast());
  1624.                 assert(switch_statement -> default_case.switch_block_statement);
  1625.  
  1626.                 DefineLabel(default_label);
  1627.             }
  1628.         }
  1629.  
  1630.         //
  1631.         // compile code for this case
  1632.         //
  1633.         for (int si = 0; si < switch_block_statement -> NumStatements(); si++)
  1634.             EmitStatement(switch_block_statement -> Statement(si) -> StatementCast());
  1635.  
  1636.         //
  1637.         // If this switch block statement does not terminate normally,
  1638.         // close the range of the locally defined variables here and
  1639.         // reset their StartPc
  1640.         //
  1641.         if (this_control.option.g)
  1642.         {
  1643.             for (int i = 0; i < switch_block_statement -> NumLocallyDefinedVariables(); i++)
  1644.             {
  1645.                 VariableSymbol *variable = switch_block_statement -> LocallyDefinedVariable(i);
  1646.  
  1647. #ifdef TEST
  1648.                 assert(method_stack -> StartPc(variable) != 0xFFFF);
  1649. #endif
  1650. #ifdef DUMP
  1651. Coutput << "(57) The symbol \"" << variable -> Name()
  1652.         << "\" numbered " << variable -> LocalVariableIndex()
  1653.         << " was released\n";
  1654. Coutput.flush();
  1655. #endif
  1656.                 local_variable_table_attribute -> AddLocalVariable(method_stack -> StartPc(variable),
  1657.                                                                    code_attribute -> CodeLength(),
  1658.                                                                    RegisterUtf8(variable -> ExternalIdentity() -> Utf8_literal),
  1659.                                                                    RegisterUtf8(variable -> Type() -> signature),
  1660.                                                                    variable -> LocalVariableIndex());
  1661. #ifdef TEST
  1662.                 method_stack -> StartPc(variable) = 0xFFFF;
  1663. #endif
  1664.             }
  1665.         }
  1666.     }
  1667.  
  1668.     //
  1669.     // If the last statement in the switch block terminates normally,
  1670.     // close the range of the locally defined variables that have
  1671.     // been defined but not yet processsed.
  1672.     //
  1673.     if (this_control.option.g)
  1674.     {
  1675.         for (int i = 0; i < switch_block -> NumLocallyDefinedVariables(); i++)
  1676.         {
  1677.             VariableSymbol *variable = switch_block -> LocallyDefinedVariable(i);
  1678.  
  1679. #ifdef TEST
  1680.             assert(method_stack -> StartPc(variable) != 0xFFFF);
  1681. #endif
  1682. #ifdef DUMP
  1683. Coutput << "(58) The symbol \"" << variable -> Name()
  1684.         << "\" numbered " << variable -> LocalVariableIndex()
  1685.         << " was released\n";
  1686. Coutput.flush();
  1687. #endif
  1688.             local_variable_table_attribute -> AddLocalVariable(method_stack -> StartPc(variable),
  1689.                                                                code_attribute -> CodeLength(),
  1690.                                                                RegisterUtf8(variable -> ExternalIdentity() -> Utf8_literal),
  1691.                                                                RegisterUtf8(variable -> Type() -> signature),
  1692.                                                                variable -> LocalVariableIndex());
  1693.         }
  1694.     }
  1695.  
  1696.     //
  1697.     //
  1698.     //
  1699.     for (int j = 0; j < nlabels; j++)
  1700.     {
  1701.         if ((case_labels[j].uses.Length() > 0) && (! case_labels[j].defined))
  1702.         {
  1703.             case_labels[j].defined = true;
  1704.             case_labels[j].definition = (switch_statement -> default_case.switch_block_statement
  1705.                                                            ? default_label.definition
  1706.                                                            : method_stack -> TopBreakLabel().definition);
  1707.         }
  1708.  
  1709.         CompleteLabel(case_labels[j]);
  1710.     }
  1711.  
  1712.     //
  1713.     // If the switch statement contains a default case, we clean up
  1714.     // the default label here.
  1715.     //
  1716.     if (switch_statement -> default_case.switch_block_statement)
  1717.         CompleteLabel(default_label);
  1718.  
  1719.     //
  1720.     // If this switch statement can be "broken", we define the break label here.
  1721.     //
  1722.     if (IsLabelUsed(method_stack -> TopBreakLabel())) // need define only if used
  1723.     {
  1724.         DefineLabel(method_stack -> TopBreakLabel());
  1725.         CompleteLabel(method_stack -> TopBreakLabel());
  1726.     }
  1727.  
  1728.     delete [] case_labels;
  1729.  
  1730.     method_stack -> Pop();
  1731.  
  1732.     return;
  1733. }
  1734.  
  1735.  
  1736. //
  1737. //  13.18       The try statement
  1738. //
  1739. void ByteCode::EmitTryStatement(AstTryStatement *statement)
  1740. {
  1741.     //
  1742.     // If the finally label in the surrounding block is used by a try statement,
  1743.     // it is cleared after the finally block associated with the try statement
  1744.     // has been processed.
  1745.     //
  1746.     assert(method_stack -> TopFinallyLabel().uses.Length() == 0);
  1747.     assert(method_stack -> TopFinallyLabel().defined == false);
  1748.     assert(method_stack -> TopFinallyLabel().definition == 0);
  1749.  
  1750.     int start_try_block_pc = code_attribute -> CodeLength(); // start pc
  1751.  
  1752.     EmitBlockStatement(statement -> block);
  1753.  
  1754.     //
  1755.     // increment max_stack in case exception thrown while stack at greatest depth
  1756.     //
  1757.     max_stack++;
  1758.  
  1759.     //
  1760.     // The computation of end_try_block_pc, the instruction following the last instruction in the
  1761.     // body of the try block, does not include the code, if any, needed to call a finally block or
  1762.     // skip to the end of the try statement.
  1763.     //
  1764.     int end_try_block_pc = code_attribute -> CodeLength(),
  1765.         special_end_pc = end_try_block_pc; // end_pc for "special" handler
  1766.  
  1767.     Label &finally_label = method_stack -> TopFinallyLabel(), // use the label in the block immediately enclosing try statement.
  1768.           end_label;
  1769.     if (statement -> block -> can_complete_normally)
  1770.     {
  1771.         if (statement -> finally_clause_opt)
  1772.         {
  1773.             //
  1774.             // Call finally block if have finally handler.
  1775.             //
  1776.             PutOp(OP_JSR);
  1777.             UseLabel(finally_label, 2, 1);
  1778.         }
  1779.  
  1780.         EmitBranch(OP_GOTO, end_label);
  1781.     }
  1782.  
  1783.     //
  1784.     // Process catch clauses, but only if try block is not empty.
  1785.     //
  1786.     if (start_try_block_pc != end_try_block_pc)
  1787.     {
  1788.         for (int i = 0; i < statement -> NumCatchClauses(); i++)
  1789.         {
  1790.             int handler_pc = code_attribute -> CodeLength();
  1791.  
  1792.             AstCatchClause *catch_clause = statement -> CatchClause(i);
  1793.             VariableSymbol *parameter_symbol = catch_clause -> parameter_symbol;
  1794.  
  1795.             StoreLocal(parameter_symbol -> LocalVariableIndex(), parameter_symbol -> Type());
  1796.  
  1797.             EmitBlockStatement(catch_clause -> block);
  1798.  
  1799.             if (this_control.option.g)
  1800.             {
  1801.                 local_variable_table_attribute -> AddLocalVariable(handler_pc,
  1802.                                                                    code_attribute -> CodeLength(),
  1803.                                                                    RegisterUtf8(parameter_symbol -> ExternalIdentity() -> Utf8_literal),
  1804.                                                                    RegisterUtf8(parameter_symbol -> Type() -> signature),
  1805.                                                                    parameter_symbol -> LocalVariableIndex());
  1806.             }
  1807.  
  1808.             code_attribute -> AddException(start_try_block_pc,
  1809.                                            end_try_block_pc,
  1810.                                            handler_pc,
  1811.                                            RegisterClass(parameter_symbol -> Type() -> fully_qualified_name));
  1812.  
  1813.             special_end_pc = code_attribute -> CodeLength();
  1814.  
  1815.             if (catch_clause -> block -> can_complete_normally)
  1816.             {
  1817.                 if (statement -> finally_clause_opt)
  1818.                 {
  1819.                     //
  1820.                     // Call finally block if have finally handler.
  1821.                     //
  1822.                     PutOp(OP_JSR);
  1823.                     UseLabel(finally_label, 2, 1);
  1824.                 }
  1825.  
  1826.                 //
  1827.                 // If there are more catch clauses, or a finally clause, then emit branch to
  1828.                 // skip over their code and on to the next statement.
  1829.                 //
  1830.                 if (statement -> finally_clause_opt || i < (statement -> NumCatchClauses() - 1))
  1831.                     EmitBranch(OP_GOTO, end_label);
  1832.             }
  1833.         }
  1834.     }
  1835.  
  1836.     //
  1837.     // If this try statement contains a finally clause, then ...
  1838.     //
  1839.     if (statement -> finally_clause_opt)
  1840.     {
  1841.         int variable_index = method_stack -> TopBlock() -> block_symbol -> try_or_synchronized_variable_index;
  1842.  
  1843.         //
  1844.         // Emit code for "special" handler to make sure finally clause is
  1845.         // invoked in case an otherwise uncaught exception is thrown in the
  1846.         // try block, or an exception is thrown from within a catch block.
  1847.         //
  1848.         // No special handler is needed if the try block is empty.
  1849.         if (start_try_block_pc != end_try_block_pc) // If try-block not empty
  1850.         {
  1851.             code_attribute -> AddException(start_try_block_pc,
  1852.                                            special_end_pc,
  1853.                                            code_attribute -> CodeLength(),
  1854.                                            0);
  1855.             StoreLocal(variable_index, this_control.Object()); // Save exception
  1856.             PutOp(OP_JSR); // Jump to finally block.
  1857.             UseLabel(finally_label, 2, 1);
  1858.             LoadLocal(variable_index, this_control.Object()); // Reload exception,
  1859.             PutOp(OP_ATHROW); // and rethrow it.
  1860.         }
  1861.  
  1862.         //
  1863.         // Generate code for finally clause.
  1864.         //
  1865.         DefineLabel(finally_label);
  1866.         CompleteLabel(finally_label);
  1867.  
  1868.         //
  1869.         // If the finally block can complete normally, save the return address.
  1870.         // Otherwise, we pop the return address from the stack.
  1871.         //
  1872.         if (statement -> finally_clause_opt -> block -> can_complete_normally)
  1873.              StoreLocal(variable_index + 1, this_control.Object());
  1874.         else PutOp(OP_POP);
  1875.  
  1876.         EmitBlockStatement(statement -> finally_clause_opt -> block);
  1877.  
  1878.         //
  1879.         // If a finally block can complete normally, after executing itsbody, we return
  1880.         // to the caller using the return address saved earlier.
  1881.         //
  1882.         if (statement -> finally_clause_opt -> block -> can_complete_normally)
  1883.             PutOpWide(OP_RET, variable_index + 1);
  1884.     }
  1885.  
  1886.     if (IsLabelUsed(end_label))
  1887.         DefineLabel(end_label);
  1888.     CompleteLabel(end_label);
  1889.  
  1890.     return;
  1891. }
  1892.  
  1893.  
  1894. //
  1895. // Exit to block at level lev, freeing monitor locks and invoking finally clauses as appropriate
  1896. //
  1897. void ByteCode::ProcessAbruptExit(int to_lev, TypeSymbol *return_type)
  1898. {
  1899.     for (int i = method_stack -> Size() - 1; i > 0 && method_stack -> NestingLevel(i) != to_lev; i--)
  1900.     {
  1901.         int nesting_level = method_stack -> NestingLevel(i),
  1902.             enclosing_level = method_stack -> NestingLevel(i - 1);
  1903.         AstBlock *block = method_stack -> Block(nesting_level);
  1904.         if (block -> block_tag == AstBlock::TRY_CLAUSE_WITH_FINALLY)
  1905.         {
  1906.             if (return_type)
  1907.             {
  1908.                 Label &finally_label = method_stack -> FinallyLabel(enclosing_level);
  1909.                 int variable_index = method_stack -> Block(enclosing_level) -> block_symbol -> try_or_synchronized_variable_index + 2;
  1910.  
  1911.                 StoreLocal(variable_index, return_type);
  1912.  
  1913.                 PutOp(OP_JSR);
  1914.                 UseLabel(finally_label, 2, 1);
  1915.  
  1916.                 LoadLocal(variable_index, return_type);
  1917.             }
  1918.             else
  1919.             {
  1920.                 PutOp(OP_JSR);
  1921.                 UseLabel(method_stack -> FinallyLabel(enclosing_level), 2, 1);
  1922.             }
  1923.         }
  1924.         else if (block -> block_tag == AstBlock::SYNCHRONIZED)
  1925.         {
  1926.             if (return_type)
  1927.             {
  1928.                 Label &monitor_label = method_stack -> MonitorLabel(enclosing_level);
  1929.                 int variable_index = method_stack -> Block(enclosing_level) -> block_symbol -> try_or_synchronized_variable_index + 2;
  1930.  
  1931.                 StoreLocal(variable_index, return_type);
  1932.  
  1933.                 PutOp(OP_JSR);
  1934.                 UseLabel(monitor_label, 2, 1);
  1935.  
  1936.                 LoadLocal(variable_index, return_type);
  1937.             }
  1938.             else
  1939.             {
  1940.                 PutOp(OP_JSR);
  1941.                 UseLabel(method_stack -> MonitorLabel(enclosing_level), 2, 1);
  1942.             }
  1943.         }
  1944.     }
  1945.  
  1946.     return;
  1947. }
  1948.  
  1949.  
  1950. //
  1951. // java provides a variety of conditional branch instructions, so
  1952. // that a number of operators merit special handling:
  1953. //      constant operand
  1954. //      negation (we eliminate it)
  1955. //      equality
  1956. //      && and || (partial evaluation)
  1957. //      comparisons
  1958. // Other expressions are just evaluated and the appropriate
  1959. // branch emitted.
  1960. //
  1961. void ByteCode::EmitBranchIfExpression(AstExpression *p, bool cond, Label &lab)
  1962. {
  1963.     if (p -> ParenthesizedExpressionCast())
  1964.         p = UnParenthesize(p);
  1965.  
  1966.     if (p -> IsConstant())
  1967.     {
  1968.         if (IsZero(p) != cond)
  1969.             EmitBranch(OP_GOTO, lab);
  1970.         return;
  1971.     }
  1972.  
  1973.     AstPreUnaryExpression *pre = p -> PreUnaryExpressionCast();
  1974.     if (pre) // must be !, though should probably
  1975.     {
  1976.         // branch_if(!e,c,l) => branch_if(e,!c,l)
  1977.         // test opcode
  1978.         // call again with complementary control expression to show
  1979.         // effect of negation
  1980.         assert(pre -> pre_unary_tag == AstPreUnaryExpression::NOT);
  1981.  
  1982.         EmitBranchIfExpression(pre -> expression, (! cond), lab);
  1983.         return;
  1984.     }
  1985.  
  1986.     //
  1987.     // dispose of non-binary expression case by just evaluating
  1988.     // operand and emitting appropiate test.
  1989.     //
  1990.     AstBinaryExpression *bp = p -> BinaryExpressionCast();
  1991.     if (! bp)
  1992.     {
  1993.         EmitExpression(p);
  1994.         EmitBranch((cond ? OP_IFNE : OP_IFEQ), lab);
  1995.         return;
  1996.     }
  1997.  
  1998.     //
  1999.     // Here if binary expression, so extract operands
  2000.     //
  2001.     AstExpression *left = bp -> left_expression;
  2002.     if (left -> ParenthesizedExpressionCast())
  2003.         left = UnParenthesize(left);
  2004.  
  2005.     AstExpression *right = bp -> right_expression;
  2006.     if (right -> ParenthesizedExpressionCast())
  2007.         right = UnParenthesize(right);
  2008.  
  2009.     TypeSymbol *left_type = left -> Type(),
  2010.                *right_type = right -> Type();
  2011.     switch (bp -> binary_tag)
  2012.     {
  2013.         case AstBinaryExpression::INSTANCEOF:
  2014.              {
  2015.                  EmitExpression(left);
  2016.                  PutOp(OP_INSTANCEOF);
  2017.                  TypeSymbol *instanceof_type = bp -> right_expression -> Type();
  2018.                  PutU2(instanceof_type -> num_dimensions > 0 ? RegisterClass(instanceof_type -> signature)
  2019.                                                              : RegisterClass(instanceof_type -> fully_qualified_name));
  2020.  
  2021.                  EmitBranch((cond ? OP_IFNE : OP_IFEQ), lab);
  2022.              }
  2023.              return;
  2024.         case AstBinaryExpression::AND_AND:
  2025.              //
  2026.              // branch_if(a&&b, true, lab) =>
  2027.              // branch_if(a,false,skip);
  2028.              // branch_if(b,true,lab);
  2029.              // skip:
  2030.              // branch_if(a&&b, false, lab) =>
  2031.              // branch_if(a,false,lab);
  2032.              // branch_if(b,false,lab);
  2033.              //
  2034.              if (cond)
  2035.              {
  2036.                  Label skip;
  2037.                  EmitBranchIfExpression(left, false, skip);
  2038.                  EmitBranchIfExpression(right, true, lab);
  2039.                  DefineLabel(skip);
  2040.                  CompleteLabel(skip);
  2041.              }
  2042.              else
  2043.              {
  2044.                  EmitBranchIfExpression(left, false, lab);
  2045.                  EmitBranchIfExpression(right, false, lab);
  2046.              }
  2047.              return;
  2048.         case AstBinaryExpression::OR_OR:
  2049.              //
  2050.              // branch_if(a||b,true,lab) =>
  2051.              // branch_if(a,true,lab);
  2052.              // branch_if(b,true,lab);
  2053.              // branch_if(a||b,false,lab) =>
  2054.              // branch_if(a,true,skip);
  2055.              // branch_if(b,false,lab);
  2056.              // There is additional possibility of one of the operands being
  2057.              // constant that should be dealt with at some point.
  2058.              //
  2059.              if (cond)
  2060.              {
  2061.                  EmitBranchIfExpression(left, true, lab);
  2062.                  EmitBranchIfExpression(right, true, lab);
  2063.              }
  2064.              else
  2065.              {
  2066.                  Label skip;
  2067.                  EmitBranchIfExpression(left, true, skip);
  2068.                  EmitBranchIfExpression(right, false, lab);
  2069.                  DefineLabel(skip);
  2070.                  CompleteLabel(skip);
  2071.              }
  2072.              return;
  2073.         case AstBinaryExpression::EQUAL_EQUAL:
  2074.         case AstBinaryExpression::NOT_EQUAL:
  2075.              //
  2076.              // One of the operands is null.
  2077.              //
  2078.              if (left_type == this_control.null_type || right_type == this_control.null_type)
  2079.              {
  2080.                  if (left_type == this_control.null_type)  // arrange so right operand is null
  2081.                  {
  2082.                      AstExpression *temp = left;
  2083.                      left = right;
  2084.                      right = temp;
  2085.  
  2086.                      left_type = left -> Type();
  2087.                      right_type = right -> Type();
  2088.                  }
  2089.  
  2090.                  EmitExpression(left);
  2091.  
  2092.                  if (bp -> binary_tag == AstBinaryExpression::EQUAL_EQUAL)
  2093.                       EmitBranch(cond ? OP_IFNULL : OP_IFNONNULL, lab);
  2094.                  else EmitBranch(cond ? OP_IFNONNULL : OP_IFNULL, lab);
  2095.  
  2096.                  return;
  2097.              }
  2098.  
  2099.              //
  2100.              // One of the operands is zero.
  2101.              //
  2102.              if (IsZero(left) || IsZero(right))
  2103.              {
  2104.                  if (IsZero(left)) // arrange so right operand is zero
  2105.                  {
  2106.                      AstExpression *temp = left;
  2107.                      left = right;
  2108.                      right = temp;
  2109.  
  2110.                      left_type = left -> Type();
  2111.                      right_type = right -> Type();
  2112.                  }
  2113.  
  2114.                  EmitExpression(left);
  2115.  
  2116.                  if (bp -> binary_tag == AstBinaryExpression::EQUAL_EQUAL)
  2117.                       EmitBranch((cond ? OP_IFEQ : OP_IFNE), lab);
  2118.                  else EmitBranch((cond ? OP_IFNE : OP_IFEQ), lab);
  2119.  
  2120.                  return;
  2121.              }
  2122.  
  2123.              //
  2124.              // both operands are integer
  2125.              //
  2126.              if ((this_control.IsSimpleIntegerValueType(left_type)  || left_type == this_control.boolean_type) &&
  2127.                  (this_control.IsSimpleIntegerValueType(right_type) || right_type == this_control.boolean_type))
  2128.              {
  2129.                  EmitExpression(left);
  2130.                  EmitExpression(right);
  2131.  
  2132.                  if (bp -> binary_tag == AstBinaryExpression::EQUAL_EQUAL)
  2133.                       EmitBranch((cond ? OP_IF_ICMPEQ : OP_IF_ICMPNE), lab);
  2134.                  else EmitBranch((cond ? OP_IF_ICMPNE : OP_IF_ICMPEQ), lab);
  2135.  
  2136.                  return;
  2137.              }
  2138.  
  2139.              //
  2140.              // Both operands are reference types: just do the comparison
  2141.              //
  2142.              if (IsReferenceType(left_type) && IsReferenceType(right_type))
  2143.              {
  2144.                  EmitExpression(left);
  2145.                  EmitExpression(right);
  2146.  
  2147.                  if (bp -> binary_tag == AstBinaryExpression::EQUAL_EQUAL)
  2148.                       EmitBranch((cond ? OP_IF_ACMPEQ : OP_IF_ACMPNE), lab);
  2149.                  else EmitBranch((cond ? OP_IF_ACMPNE : OP_IF_ACMPEQ), lab);
  2150.  
  2151.                  return;
  2152.              }
  2153.  
  2154.              break;
  2155.  
  2156.         default:
  2157.              break;
  2158.     }
  2159.  
  2160.     //
  2161.     // here if not comparison, comparison for non-integral numeric types, or
  2162.     // integral comparison for which no special casing needed.
  2163.     // Begin by dealing with non-comparisons
  2164.     //
  2165.     switch(bp -> binary_tag)
  2166.     {
  2167.         case AstBinaryExpression::LESS:
  2168.         case AstBinaryExpression::LESS_EQUAL:
  2169.         case AstBinaryExpression::GREATER:
  2170.         case AstBinaryExpression::GREATER_EQUAL:
  2171.         case AstBinaryExpression::EQUAL_EQUAL:
  2172.         case AstBinaryExpression::NOT_EQUAL:
  2173.              break; // break to continue comparison processing
  2174.         default:
  2175.              //
  2176.              // not a comparison, get the (necessarily boolean) value
  2177.              // of the expression and branch on the result
  2178.              //
  2179.              EmitExpression(p);
  2180.              EmitBranch(cond ? OP_IFNE : OP_IFEQ, lab);
  2181.              return;
  2182.     }
  2183.  
  2184.     //
  2185.     //
  2186.     //
  2187.     unsigned opcode = 0,
  2188.              op_true,
  2189.              op_false;
  2190.     if (this_control.IsSimpleIntegerValueType(left_type) || left_type == this_control.boolean_type)
  2191.     {
  2192.         //
  2193.         // we have already dealt with EQUAL_EQUAL and NOT_EQUAL for the case
  2194.         // of two integers, but still need to look for comparisons for which
  2195.         // one operand may be zero.
  2196.         //
  2197.         if (IsZero(left))
  2198.         {
  2199.             EmitExpression(right);
  2200.             switch(bp -> binary_tag)
  2201.             {
  2202.                 case AstBinaryExpression::LESS: // if (0 < x) same as  if (x > 0)
  2203.                      op_true = OP_IFGT;
  2204.                      op_false = OP_IFLE;
  2205.                      break;
  2206.                 case AstBinaryExpression::LESS_EQUAL:  // if (0 <= x) same as if (x >= 0)
  2207.                      op_true = OP_IFGE;
  2208.                      op_false = OP_IFLT;
  2209.                      break;
  2210.                 case AstBinaryExpression::GREATER:  // if (0 > x) same as if (x < 0)
  2211.                      op_true = OP_IFLT;
  2212.                      op_false = OP_IFGE;
  2213.                      break;
  2214.                 case AstBinaryExpression::GREATER_EQUAL: // if (0 >= x) same as if (x <= 0)
  2215.                      op_true = OP_IFLE;
  2216.                      op_false = OP_IFGT;
  2217.                      break;
  2218.                 default:
  2219.                     assert(false);
  2220.                     break;
  2221.             }
  2222.         }
  2223.         else if (IsZero(right))
  2224.         {
  2225.             EmitExpression(left);
  2226.  
  2227.             switch(bp -> binary_tag)
  2228.             {
  2229.                 case AstBinaryExpression::LESS:
  2230.                      op_true = OP_IFLT;
  2231.                      op_false = OP_IFGE;
  2232.                      break;
  2233.                 case AstBinaryExpression::LESS_EQUAL:
  2234.                      op_true = OP_IFLE;
  2235.                      op_false = OP_IFGT;
  2236.                      break;
  2237.                 case AstBinaryExpression::GREATER:
  2238.                      op_true = OP_IFGT;
  2239.                      op_false = OP_IFLE;
  2240.                      break;
  2241.                 case AstBinaryExpression::GREATER_EQUAL:
  2242.                      op_true = OP_IFGE;
  2243.                      op_false = OP_IFLT;
  2244.                      break;
  2245.                 default:
  2246.                     assert(false);
  2247.                     break;
  2248.             }
  2249.         }
  2250.         else
  2251.         {
  2252.             EmitExpression(left);
  2253.             EmitExpression(right);
  2254.  
  2255.             switch(bp -> binary_tag)
  2256.             {
  2257.                 case AstBinaryExpression::LESS:
  2258.                      op_true = OP_IF_ICMPLT;
  2259.                      op_false = OP_IF_ICMPGE;
  2260.                      break;
  2261.                 case AstBinaryExpression::LESS_EQUAL:
  2262.                      op_true = OP_IF_ICMPLE;
  2263.                      op_false = OP_IF_ICMPGT;
  2264.                      break;
  2265.                 case AstBinaryExpression::GREATER:
  2266.                      op_true = OP_IF_ICMPGT;
  2267.                      op_false = OP_IF_ICMPLE;
  2268.                      break;
  2269.                 case AstBinaryExpression::GREATER_EQUAL:
  2270.                      op_true = OP_IF_ICMPGE;
  2271.                      op_false = OP_IF_ICMPLT;
  2272.                      break;
  2273.                 default:
  2274.                     assert(false);
  2275.                     break;
  2276.             }
  2277.         }
  2278.     }
  2279.     else if (left_type == this_control.long_type)
  2280.     {
  2281.         EmitExpression(left);
  2282.         EmitExpression(right);
  2283.  
  2284.         opcode = OP_LCMP;
  2285.  
  2286.         //
  2287.         // branch according to result value on stack
  2288.         //
  2289.         switch (bp -> binary_tag)
  2290.         {
  2291.             case AstBinaryExpression::EQUAL_EQUAL:
  2292.                  op_true = OP_IFEQ;
  2293.                  op_false = OP_IFNE;
  2294.                  break;
  2295.             case AstBinaryExpression::NOT_EQUAL:
  2296.                  op_true = OP_IFNE;
  2297.                  op_false = OP_IFEQ;
  2298.                  break;
  2299.             case AstBinaryExpression::LESS:
  2300.                  op_true = OP_IFLT;
  2301.                  op_false = OP_IFGE;
  2302.                  break;
  2303.             case AstBinaryExpression::LESS_EQUAL:
  2304.                  op_true = OP_IFLE;
  2305.                  op_false = OP_IFGT;
  2306.                  break;
  2307.             case AstBinaryExpression::GREATER:
  2308.                  op_true = OP_IFGT;
  2309.                  op_false = OP_IFLE;
  2310.                  break;
  2311.             case AstBinaryExpression::GREATER_EQUAL:
  2312.                  op_true = OP_IFGE;
  2313.                  op_false = OP_IFLT;
  2314.                  break;
  2315.             default:
  2316.                 assert(false);
  2317.                 break;
  2318.         }
  2319.     }
  2320.     else if (left_type == this_control.float_type)
  2321.     {
  2322.         EmitExpression(left);
  2323.         EmitExpression(right);
  2324.  
  2325.         switch (bp -> binary_tag)
  2326.         {
  2327.             case AstBinaryExpression::EQUAL_EQUAL:
  2328.                  opcode = OP_FCMPL;
  2329.                  op_true = OP_IFEQ;
  2330.                  op_false = OP_IFNE;
  2331.                  break;
  2332.             case AstBinaryExpression::NOT_EQUAL:
  2333.                  opcode = OP_FCMPL;
  2334.                  op_true = OP_IFNE;
  2335.                  op_false = OP_IFEQ;
  2336.                  break;
  2337.             case AstBinaryExpression::LESS:
  2338.                  opcode = OP_FCMPG;
  2339.                  op_true = OP_IFLT;
  2340.                  op_false = OP_IFGE;
  2341.                  break;
  2342.             case AstBinaryExpression::LESS_EQUAL:
  2343.                  opcode = OP_FCMPG;
  2344.                  op_true = OP_IFLE;
  2345.                  op_false = OP_IFGT;
  2346.                  break;
  2347.             case AstBinaryExpression::GREATER:
  2348.                  opcode = OP_FCMPL;
  2349.                  op_true = OP_IFGT;
  2350.                  op_false = OP_IFLE;
  2351.                  break;
  2352.             case AstBinaryExpression::GREATER_EQUAL:
  2353.                  opcode = OP_FCMPL;
  2354.                  op_true = OP_IFGE;
  2355.                  op_false = OP_IFLT;
  2356.                  break;
  2357.             default:
  2358.                 assert(false);
  2359.                 break;
  2360.         }
  2361.     }
  2362.     else if (left_type == this_control.double_type)
  2363.     {
  2364.         EmitExpression(left);
  2365.         EmitExpression(right);
  2366.         switch (bp -> binary_tag)
  2367.         {
  2368.             case AstBinaryExpression::EQUAL_EQUAL:
  2369.                  opcode = OP_DCMPL;
  2370.                  op_true = OP_IFEQ;
  2371.                  op_false = OP_IFNE;
  2372.                  break;
  2373.             case AstBinaryExpression::NOT_EQUAL:
  2374.                  opcode = OP_DCMPL;
  2375.                  op_true = OP_IFNE;
  2376.                  op_false = OP_IFEQ;
  2377.                  break;
  2378.             case AstBinaryExpression::LESS:
  2379.                  opcode = OP_DCMPG;
  2380.                  op_true = OP_IFLT;
  2381.                  op_false = OP_IFGE;
  2382.                  break;
  2383.             case AstBinaryExpression::LESS_EQUAL:
  2384.                  opcode = OP_DCMPG;
  2385.                  op_true = OP_IFLE;
  2386.                  op_false = OP_IFGT;
  2387.                  break;
  2388.             case AstBinaryExpression::GREATER:
  2389.                  opcode = OP_DCMPL;
  2390.                  op_true = OP_IFGT;
  2391.                  op_false = OP_IFLE;
  2392.                  break;
  2393.             case AstBinaryExpression::GREATER_EQUAL:
  2394.                  opcode = OP_DCMPL;
  2395.                  op_true = OP_IFGE;
  2396.                  op_false = OP_IFLT;
  2397.                  break;
  2398.             default:
  2399.                 assert(false);
  2400.                 break;
  2401.         }
  2402.     }
  2403.     else assert(false && "comparison of unsupported type");
  2404.  
  2405.     if (opcode)
  2406.         PutOp(opcode); // if need to emit comparison before branch
  2407.  
  2408.     EmitBranch (cond ? op_true : op_false, lab);
  2409.  
  2410.     return;
  2411. }
  2412.  
  2413.  
  2414. void ByteCode::EmitSynchronizedStatement(AstSynchronizedStatement *statement)
  2415. {
  2416.     EmitExpression(statement -> expression);
  2417.  
  2418.     int variable_index = method_stack -> TopBlock() -> block_symbol -> try_or_synchronized_variable_index;
  2419.  
  2420.     StoreLocal(variable_index, this_control.Object()); // save address of object
  2421.     LoadLocal(variable_index, this_control.Object()); // load address of object onto stack
  2422.  
  2423.     PutOp(OP_MONITORENTER); // enter monitor associated with object
  2424.  
  2425.     int start_synchronized_pc = code_attribute -> CodeLength(); // start pc
  2426.  
  2427.     EmitBlockStatement(statement -> block);
  2428.  
  2429.     int end_synchronized_pc = code_attribute -> CodeLength(); // end pc
  2430.  
  2431.     LoadLocal(variable_index, this_control.Object()); // load address of object onto stack
  2432.     PutOp(OP_MONITOREXIT);
  2433.  
  2434.     if (start_synchronized_pc != end_synchronized_pc) // if the synchronized block is not empty.
  2435.     {
  2436.         Label end_label;
  2437.         EmitBranch(OP_GOTO, end_label); // branch around exception handler
  2438.  
  2439.         //
  2440.         // Reach here if any increment. max_stack in case exception thrown while stack at greatest depth
  2441.         //
  2442.         max_stack++;
  2443.         int handler_pc = code_attribute -> CodeLength();
  2444.         LoadLocal(variable_index, this_control.Object()); // load address of object onto stack
  2445.         PutOp(OP_MONITOREXIT);
  2446.         PutOp(OP_ATHROW);
  2447.  
  2448.         code_attribute -> AddException(start_synchronized_pc, handler_pc, handler_pc, 0);
  2449.  
  2450.         DefineLabel(method_stack -> TopMonitorLabel());
  2451.         CompleteLabel(method_stack -> TopMonitorLabel());
  2452.  
  2453.         int loc_index = variable_index + 1; // local variable index to save return  address
  2454.         StoreLocal(loc_index, this_control.Object()); // save return address
  2455.         LoadLocal(variable_index, this_control.Object()); // load address of object onto stack
  2456.         PutOp(OP_MONITOREXIT);
  2457.         PutOpWide(OP_RET, loc_index);  // return using saved address
  2458.  
  2459.         DefineLabel(end_label);
  2460.         CompleteLabel(end_label);
  2461.     }
  2462.  
  2463.     return;
  2464. }
  2465.  
  2466.  
  2467. //
  2468. // JLS is Java Language Specification
  2469. // JVM is Java Virtual Machine
  2470. //
  2471. // Expressions: Chapter 14 of JLS
  2472. //
  2473. int ByteCode::EmitExpression(AstExpression *expression)
  2474. {
  2475.     if (expression -> IsConstant())
  2476.     {
  2477.         LoadLiteral(expression -> value, expression -> Type());
  2478.         return (this_control.IsDoubleWordType(expression -> Type()) ? 2 : 1);
  2479.     }
  2480.  
  2481.     switch (expression -> kind)
  2482.     {
  2483.         case Ast::IDENTIFIER:
  2484.              {
  2485.                  AstSimpleName *simple_name = expression -> SimpleNameCast();
  2486.                  return (simple_name -> resolution_opt ? EmitExpression(simple_name -> resolution_opt)
  2487.                                                        : LoadVariable(GetLhsKind(expression), expression));
  2488.              }
  2489.         case Ast::THIS_EXPRESSION:
  2490.         case Ast::SUPER_EXPRESSION:
  2491.              PutOp(OP_ALOAD_0); // must be use
  2492.              return 1;
  2493.         case Ast::PARENTHESIZED_EXPRESSION:
  2494.              return EmitExpression(((AstParenthesizedExpression *) expression) -> expression);
  2495.         case Ast::CLASS_CREATION:
  2496.              return EmitClassInstanceCreationExpression((AstClassInstanceCreationExpression *) expression, true);
  2497.         case Ast::ARRAY_CREATION:
  2498.              return EmitArrayCreationExpression((AstArrayCreationExpression *) expression);
  2499.         case Ast::DIM:
  2500.              return EmitExpression(expression -> DimExprCast() -> expression);
  2501.         case Ast::DOT:
  2502.              {
  2503.                  AstFieldAccess *field_access = (AstFieldAccess *) expression;
  2504.                  return ((field_access -> IsClassAccess()) && (field_access -> resolution_opt))
  2505.                                                             ? (unit_type -> outermost_type -> ACC_INTERFACE()
  2506.                                                                           ? EmitExpression(field_access -> resolution_opt)
  2507.                                                                           : GenerateClassAccess(field_access))
  2508.                                                             : EmitFieldAccess(field_access);
  2509.              }
  2510.         case Ast::CALL:
  2511.              {
  2512.                  AstMethodInvocation *method_call = expression -> MethodInvocationCast();
  2513.                  EmitMethodInvocation(method_call);
  2514.                  return GetTypeWords(method_call -> Type());
  2515.              }
  2516.         case Ast::ARRAY_ACCESS:             // if seen alone this will be as RHS
  2517.              return EmitArrayAccessRhs((AstArrayAccess *) expression);
  2518.         case Ast::POST_UNARY:
  2519.              return EmitPostUnaryExpression((AstPostUnaryExpression *) expression, true);
  2520.         case Ast::PRE_UNARY:
  2521.              return EmitPreUnaryExpression((AstPreUnaryExpression *) expression, true);
  2522.         case Ast::CAST:
  2523.              {
  2524.                  AstCastExpression *cast_expression = (AstCastExpression *) expression;
  2525.  
  2526.                  //
  2527.                  // only primitive types require casting
  2528.                  //
  2529.                  return (cast_expression -> expression -> Type() -> Primitive()
  2530.                                           ? EmitCastExpression(cast_expression)
  2531.                                           : EmitExpression(cast_expression -> expression));
  2532.              }
  2533.         case Ast::CHECK_AND_CAST:
  2534.              return EmitCastExpression((AstCastExpression *) expression);
  2535.         case Ast::BINARY:
  2536.              return EmitBinaryExpression((AstBinaryExpression *) expression);
  2537.         case Ast::CONDITIONAL:
  2538.              return EmitConditionalExpression((AstConditionalExpression *) expression);
  2539.         case Ast::ASSIGNMENT:
  2540.              return EmitAssignmentExpression((AstAssignmentExpression *) expression, true);
  2541.         default:
  2542.              assert(false && "unknown expression kind");
  2543.              break;
  2544.      }
  2545.  
  2546.      return 0; // even though we will not reach here
  2547. }
  2548.  
  2549.  
  2550. AstExpression *ByteCode::VariableExpressionResolution(AstExpression *expression)
  2551. {
  2552.     AstFieldAccess *field = expression -> FieldAccessCast();
  2553.     AstSimpleName *simple_name = expression -> SimpleNameCast();
  2554.  
  2555.     //
  2556.     // If the expression was resolved, get the resolution
  2557.     //
  2558.     if (field)
  2559.     {
  2560.         if (field -> resolution_opt)
  2561.            expression = field -> resolution_opt;
  2562.     }
  2563.     else if (simple_name)
  2564.     {
  2565.         if (simple_name -> resolution_opt)
  2566.             expression = simple_name -> resolution_opt;
  2567.     }
  2568.  
  2569.     return expression;
  2570. }
  2571.  
  2572.  
  2573. TypeSymbol *ByteCode::VariableTypeResolution(AstExpression *expression, VariableSymbol *sym)
  2574. {
  2575.     expression = VariableExpressionResolution(expression);
  2576.     AstFieldAccess *field = expression -> FieldAccessCast();
  2577.     AstSimpleName *simple_name = expression -> SimpleNameCast();
  2578.     assert(field || simple_name);
  2579.  
  2580.     TypeSymbol *owner_type = sym -> owner -> TypeCast(),
  2581.                *base_type = (field ? field -> base -> Type() : unit_type);
  2582.  
  2583.     // If the real owner of the field is either public or contained in
  2584.     // the same package as the current unit then the type used in the
  2585.     // fieldref should be the owner. Otherwise, the base_type is used.
  2586.     //
  2587.     return (owner_type -> ACC_PUBLIC() || owner_type -> ContainingPackage() == unit_type -> ContainingPackage()
  2588.             ? owner_type
  2589.             : base_type);
  2590.  
  2591. }
  2592.  
  2593.  
  2594. TypeSymbol *ByteCode::MethodTypeResolution(AstExpression *method_name, MethodSymbol *msym)
  2595. {
  2596.     AstFieldAccess *field = method_name -> FieldAccessCast();
  2597.     AstSimpleName *simple_name = method_name -> SimpleNameCast();
  2598.     assert(field || simple_name);
  2599.  
  2600.     TypeSymbol *owner_type = msym -> containing_type,
  2601.                *base_type = (field ? field -> base -> Type()
  2602.                                    : (simple_name -> resolution_opt ? simple_name -> resolution_opt -> Type() : owner_type));
  2603.  
  2604.  
  2605.      //
  2606.      // If the real owner of the method is an array type then Object
  2607.      // is used in the methodref. Otherwise, if the owner is public
  2608.      // or it is contained in the same package as the current unit
  2609.      // then the base_type is used.
  2610.      //
  2611.     return (owner_type -> IsArray()
  2612.             ? this_control.Object()
  2613.             : owner_type -> ACC_PUBLIC() || owner_type -> ContainingPackage() == unit_type -> ContainingPackage()
  2614.             ? owner_type
  2615.             : base_type);
  2616. }
  2617.  
  2618.  
  2619. void ByteCode::EmitFieldAccessLhsBase(AstExpression *expression)
  2620. {
  2621.     expression = VariableExpressionResolution(expression);
  2622.     AstFieldAccess *field = expression -> FieldAccessCast();
  2623.  
  2624.     //
  2625.     // We now have the right expression. Check if it's a field. If so, process base
  2626.     // Otherwise, it must be a simple name...
  2627.     //
  2628.     field = expression -> FieldAccessCast();
  2629.     if (field)
  2630.         EmitExpression(field -> base);
  2631.     else
  2632.     {
  2633.         assert(expression -> SimpleNameCast() && "unexpected AssignmentExpressionField operand base type");
  2634.  
  2635.         PutOp(OP_ALOAD_0); // get address of "this"
  2636.     }
  2637.  
  2638.     return;
  2639. }
  2640.  
  2641.  
  2642. void ByteCode::EmitFieldAccessLhs(AstExpression *expression)
  2643. {
  2644.     EmitFieldAccessLhsBase(expression);
  2645.     PutOp(OP_DUP);     // save base address of field for later store
  2646.     PutOp(OP_GETFIELD);
  2647.     ChangeStack(this_control.IsDoubleWordType(expression -> Type()) ? 1 : 0);
  2648.  
  2649.     VariableSymbol *sym = (VariableSymbol *) expression -> symbol;
  2650.     PutU2(RegisterFieldref(VariableTypeResolution(expression, sym), sym));
  2651.  
  2652.     return;
  2653. }
  2654.  
  2655.  
  2656. //
  2657. // Generate code for access method used to set class literal fields
  2658. //
  2659. void ByteCode::GenerateClassAccessMethod(MethodSymbol *msym)
  2660. {
  2661.     //
  2662.     // The code takes the form:
  2663.     //
  2664.     //  aload_0          load this
  2665.     //  invokestatic     java/lang/Class.forName(String)java/lang/Class
  2666.     //  areturn          return Class object for the class named by string
  2667.     //
  2668.     //  exception handler if forName fails:
  2669.     //
  2670.     //  astore_1         save exception
  2671.     //  new              java.lang.NoClassDefFoundError
  2672.     //  dup              save so can return
  2673.     //  aload_1          recover exception
  2674.     //  invokevirtual    java.lang.Throwable.getMessage() to get error message
  2675.     //  invokenonvirtual <init>     // invoke initializer
  2676.     //  athrow           rethrow the exception
  2677.     //
  2678.     PutOp(OP_ALOAD_0);
  2679.     PutOp(OP_INVOKESTATIC);
  2680.     ChangeStack(-1);
  2681.     PutU2(RegisterLibraryMethodref(this_control.Class_forNameMethod()));
  2682.     ChangeStack(1);
  2683.  
  2684.     PutOp(OP_ARETURN);
  2685.     PutOp(OP_ASTORE_1);
  2686.     PutOp(OP_NEW);
  2687.     PutU2(RegisterClass(this_control.NoClassDefFoundError() -> fully_qualified_name));
  2688.     PutOp(OP_DUP);
  2689.     PutOp(OP_ALOAD_1);
  2690.     PutOp(OP_INVOKEVIRTUAL);
  2691.     ChangeStack(-1);
  2692.     PutU2(RegisterLibraryMethodref(this_control.Throwable_getMessageMethod()));
  2693.     ChangeStack(1);
  2694.  
  2695.     PutOp(OP_INVOKENONVIRTUAL);
  2696.     ChangeStack(-1);
  2697.     PutU2(RegisterLibraryMethodref(this_control.NoClassDefFoundError_InitMethod()));
  2698.  
  2699.     ChangeStack(1);
  2700.     PutOp(OP_ATHROW);
  2701.  
  2702.     max_stack = 3;
  2703.  
  2704.     code_attribute -> AddException(0,
  2705.                                    5,
  2706.                                    5,
  2707.                                    RegisterClass(this_control.ClassNotFoundException() -> fully_qualified_name));
  2708.  
  2709.     return;
  2710. }
  2711.  
  2712.  
  2713. //
  2714. // here to generate code to dymanically initialize the field for a class literal and then return its value
  2715. //
  2716. int ByteCode::GenerateClassAccess(AstFieldAccess *field_access)
  2717. {
  2718.     //
  2719.     // simple case in immediate environment, can use field on both left and right
  2720.     // (TypeSymbol *type)
  2721.     // evaluate X.class literal. If X is a primitive type, this is a predefined field;
  2722.     // otherwise, we must create a new synthetic field to hold the desired result and
  2723.     // initialize it at runtime.
  2724.     // generate
  2725.     // getstatic class_field     load class field
  2726.     // ifnull lab1               branch if not yet set
  2727.     // get class_field           here if set, return value
  2728.     // goto lab2
  2729.     // lab1:                     here to initialize the field
  2730.     // load class_constant       get name of class
  2731.     // invokestatic              invoke generated method to get class_field  desired value
  2732.     // dup                       save value so can return it
  2733.     // put class_field           initialize the field
  2734.     // lab2:
  2735.     //
  2736.     Label lab1,
  2737.           lab2;
  2738.     if (field_access -> symbol -> VariableCast())
  2739.     {
  2740.         u2 field_index = RegisterFieldref(field_access -> symbol -> VariableCast());
  2741.  
  2742.         PutOp(OP_GETSTATIC);
  2743.         PutU2(field_index);
  2744.         ChangeStack(1);
  2745.         EmitBranch(OP_IFNULL, lab1);
  2746.         PutOp(OP_GETSTATIC);
  2747.         PutU2(field_index);
  2748.         ChangeStack(1);
  2749.         EmitBranch(OP_GOTO, lab2);
  2750.         DefineLabel(lab1);
  2751.  
  2752.         //
  2753.         // generate load of constant naming the class
  2754.         //
  2755.         LoadLiteral(field_access -> base -> Type() -> ClassLiteralName(), this_control.String());
  2756.         PutOp(OP_INVOKESTATIC);
  2757.         CompleteCall(unit_type -> outermost_type -> ClassLiteralMethod(), 1);
  2758.         PutOp(OP_DUP);
  2759.         PutOp(OP_PUTSTATIC);
  2760.         PutU2(field_index);
  2761.         ChangeStack(-1);
  2762.     }
  2763.     else // here in nested case, where must invoke access methods for the field
  2764.     {
  2765.         MethodSymbol *read_symbol = field_access -> symbol -> MethodCast(),
  2766.                      *write_symbol = field_access -> resolution_opt -> symbol -> MethodCast();
  2767.  
  2768.         //
  2769.         // need load this for class with method
  2770.         // if the next statement read field_access -> resolution_opt -> symbol = read_method, then
  2771.         // generating code for that expression tree would give us what we want
  2772.         //
  2773.         // TODO: THIS DOES NOT SEEM TO HAVE ANY PURPOSE. BESIDES, IT CHANGES THE INTERMEDIATE REPRESENTATION !!!
  2774.         //
  2775.         //        field_access -> resolution_opt -> symbol = read_symbol;
  2776.         //
  2777.  
  2778.         PutOp(OP_INVOKESTATIC);
  2779.         u2 read_ref = RegisterMethodref(read_symbol -> containing_type -> fully_qualified_name,
  2780.                                         read_symbol -> ExternalIdentity() -> Utf8_literal,
  2781.                                         read_symbol -> signature);
  2782.         PutU2(read_ref);
  2783.         ChangeStack(1);
  2784.  
  2785.         EmitBranch(OP_IFNULL, lab1);
  2786.         PutOp(OP_INVOKESTATIC);
  2787.         PutU2(read_ref);
  2788.         ChangeStack(1);
  2789.         EmitBranch(OP_GOTO, lab2);
  2790.         DefineLabel(lab1);
  2791.  
  2792.         //
  2793.         // generate load of constant naming the class
  2794.         //
  2795.         LoadLiteral(field_access -> base -> Type() -> ClassLiteralName(), this_control.String());
  2796.         PutOp(OP_INVOKESTATIC);
  2797.         CompleteCall(unit_type -> outermost_type -> ClassLiteralMethod(), 1);
  2798.         PutOp(OP_DUP);
  2799.         PutOp(OP_INVOKESTATIC);
  2800.  
  2801.         u2 write_ref = RegisterMethodref(write_symbol -> containing_type -> fully_qualified_name,
  2802.                                          write_symbol -> ExternalIdentity() -> Utf8_literal,
  2803.                                          write_symbol -> signature);
  2804.         PutU2(write_ref);
  2805.         ChangeStack(-1); // to indicate argument popped
  2806.     }
  2807.  
  2808.     DefineLabel(lab2);
  2809.     CompleteLabel(lab1);
  2810.     CompleteLabel(lab2);
  2811.  
  2812.     return 1; // return one-word (reference) result
  2813. }
  2814.  
  2815.  
  2816. //
  2817. // see also OP_MULTINEWARRAY
  2818. //
  2819. int ByteCode::EmitArrayCreationExpression(AstArrayCreationExpression *expression)
  2820. {
  2821.     int num_dims = expression -> NumDimExprs();
  2822.  
  2823.     if (num_dims > 255)
  2824.     {
  2825.         this_semantic.ReportSemError(SemanticError::ARRAY_OVERFLOW,
  2826.                                      expression -> LeftToken(),
  2827.                                      expression -> RightToken());
  2828.     }
  2829.  
  2830.     if (expression -> array_initializer_opt)
  2831.         InitializeArray(expression -> Type(), expression -> array_initializer_opt);
  2832.     else
  2833.     {
  2834.         //
  2835.         // need to push value of dimension(s)
  2836.         //
  2837.         for (int i = 0; i < num_dims; i++)
  2838.             EmitExpression(expression -> DimExpr(i) -> expression);
  2839.  
  2840.         EmitNewArray(num_dims, expression -> Type());
  2841.     }
  2842.  
  2843.     return 1;
  2844. }
  2845.  
  2846.  
  2847. //
  2848. // ASSIGNMENT
  2849. //
  2850. int ByteCode::EmitAssignmentExpression(AstAssignmentExpression *assignment_expression, bool need_value)
  2851. {
  2852.     AstCastExpression *casted_left_hand_side = assignment_expression -> left_hand_side -> CastExpressionCast();
  2853.     AstExpression *left_hand_side = (casted_left_hand_side ? casted_left_hand_side -> expression : assignment_expression -> left_hand_side);
  2854.  
  2855.     TypeSymbol *left_type = left_hand_side -> Type();
  2856.  
  2857.     int kind = GetLhsKind(assignment_expression);
  2858.     VariableSymbol *accessed_member = (assignment_expression -> write_method
  2859.                                                    ? assignment_expression -> write_method -> accessed_member -> VariableCast()
  2860.                                                    : (VariableSymbol *) NULL);
  2861.  
  2862.     if (assignment_expression -> SimpleAssignment())
  2863.     {
  2864.         switch(kind)
  2865.         {
  2866.             case LHS_ARRAY:
  2867.                  EmitArrayAccessLhs(left_hand_side -> ArrayAccessCast()); // lhs must be array access
  2868.                  break;
  2869.             case LHS_FIELD:
  2870.                  EmitFieldAccessLhsBase(left_hand_side); // load base for field access
  2871.                  break;
  2872.             case LHS_METHOD:
  2873.                  if (! accessed_member -> ACC_STATIC()) // need to load address of object, obtained from resolution
  2874.                  {
  2875.                      AstExpression *resolve = (left_hand_side -> FieldAccessCast()
  2876.                                                                ? left_hand_side -> FieldAccessCast() -> resolution_opt
  2877.                                                                : left_hand_side -> SimpleNameCast() -> resolution_opt);
  2878.  
  2879.                      assert(resolve);
  2880.  
  2881.                      AstFieldAccess *field_expression = resolve -> MethodInvocationCast() -> method -> FieldAccessCast();
  2882.  
  2883.                      assert(field_expression);
  2884.  
  2885.                      EmitExpression(field_expression -> base);
  2886.                  }
  2887.                  break;
  2888.             default:
  2889.                  break;
  2890.         }
  2891.  
  2892.         EmitExpression(assignment_expression -> expression);
  2893.     }
  2894.     //
  2895.     // Here for compound assignment. Get the left operand, saving any information necessary to
  2896.     // update its value on the stack below the value.
  2897.     //
  2898.     else
  2899.     {
  2900.         switch(kind)
  2901.         {
  2902.             case LHS_ARRAY:
  2903.                  EmitArrayAccessLhs(left_hand_side -> ArrayAccessCast()); // lhs must be array access
  2904.                  PutOp(OP_DUP2); // save base and index for later store
  2905.  
  2906.                  //
  2907.                  // load current value
  2908.                  //
  2909.                  (void) LoadArrayElement(assignment_expression -> Type());
  2910.                  break;
  2911.             case LHS_FIELD:
  2912.                  EmitFieldAccessLhs(left_hand_side);
  2913.                  break;
  2914.             case LHS_LOCAL:
  2915.                  if ((! casted_left_hand_side) &&
  2916.                      assignment_expression -> Type() == this_control.int_type &&
  2917.                      assignment_expression -> expression -> IsConstant() &&
  2918.                      (assignment_expression -> assignment_tag == AstAssignmentExpression::PLUS_EQUAL ||
  2919.                       assignment_expression -> assignment_tag == AstAssignmentExpression::MINUS_EQUAL))
  2920.                  {
  2921.                      IntLiteralValue *vp = (IntLiteralValue *) assignment_expression -> expression -> value;
  2922.                      int val = (assignment_expression -> assignment_tag == AstAssignmentExpression::MINUS_EQUAL
  2923.                                                                          ? -(vp -> value) // we treat "a -= x" as "a += (-x)"
  2924.                                                                          : vp -> value);
  2925.                      if (val >= -32768 && val < 32768) // if value in range
  2926.                      {
  2927.                          VariableSymbol *sym = (VariableSymbol *) left_hand_side -> symbol;
  2928.                          PutOpIINC(sym -> LocalVariableIndex(), val);
  2929.                          if (need_value)
  2930.                              LoadVariable(LHS_LOCAL, left_hand_side);
  2931.                          return GetTypeWords(assignment_expression -> Type());
  2932.                      }
  2933.                  }
  2934.  
  2935.                  (void) LoadVariable(kind, left_hand_side);
  2936.                  break;
  2937.             case LHS_STATIC:
  2938.                  (void) LoadVariable(kind, left_hand_side);
  2939.                  //
  2940.                  // TODO:
  2941.                  // see if actually need call to ChangeStack, marked CHECK_THIS, in AssigmnentExpression
  2942.                  //
  2943.                  // ChangeStack(this_control.IsDoubleWordType(left_type) ? 1: 0); // CHECK_THIS? Is this really necessary
  2944.                  //
  2945.                  break;
  2946.             case LHS_METHOD:
  2947.                  //
  2948.                  // If we are accessing a static member, get value by invoking appropriate resolution.
  2949.                  // Otherwise, in addition to getting the value, we need to load address of the object,
  2950.                  // obtained from the resolution, saving a copy on the stack.
  2951.                  //
  2952.                  if (accessed_member -> ACC_STATIC())
  2953.                       EmitExpression(left_hand_side);
  2954.                  else ResolveAccess(left_hand_side);
  2955.                  break;
  2956.             default:
  2957.                  break;
  2958.         }
  2959.  
  2960.         //
  2961.         // Here for string concatenation.
  2962.         //
  2963.         if (assignment_expression -> assignment_tag == AstAssignmentExpression::PLUS_EQUAL && left_type == this_control.String())
  2964.         {
  2965.             PutOp(OP_NEW);
  2966.             PutU2(RegisterClass(this_control.StringBuffer() -> fully_qualified_name));
  2967.             PutOp(OP_DUP);
  2968.             PutOp(OP_INVOKENONVIRTUAL);
  2969.             PutU2(RegisterLibraryMethodref(this_control.StringBuffer_InitMethod()));
  2970.             PutOp(OP_SWAP); // swap address if buffer and string to update.
  2971.             EmitStringAppendMethod(this_control.String());
  2972.             AppendString(assignment_expression -> expression);
  2973.  
  2974.             //
  2975.             // convert string buffer to string
  2976.             //
  2977.             PutOp(OP_INVOKEVIRTUAL);
  2978.             PutU2(RegisterLibraryMethodref(this_control.StringBuffer_toStringMethod()));
  2979.             ChangeStack(1); // account for return value
  2980.         }
  2981.         //
  2982.         // Here for operation other than string concatenation. Determine the opcode to use.
  2983.         //
  2984.         else
  2985.         {
  2986.             int opc;
  2987.  
  2988.             TypeSymbol *op_type = (casted_left_hand_side ? casted_left_hand_side -> Type() : assignment_expression -> Type());
  2989.  
  2990.             if (this_control.IsSimpleIntegerValueType(op_type) || op_type == this_control.boolean_type)
  2991.             {
  2992.                 switch (assignment_expression -> assignment_tag)
  2993.                 {
  2994.                     case AstAssignmentExpression::STAR_EQUAL:
  2995.                          opc = OP_IMUL;
  2996.                          break;
  2997.                     case AstAssignmentExpression::SLASH_EQUAL:
  2998.                          opc = OP_IDIV;
  2999.                          break;
  3000.                     case AstAssignmentExpression::MOD_EQUAL:
  3001.                          opc = OP_IREM;
  3002.                          break;
  3003.                     case AstAssignmentExpression::PLUS_EQUAL:
  3004.                          opc = OP_IADD;
  3005.                          break;
  3006.                     case AstAssignmentExpression::MINUS_EQUAL:
  3007.                          opc = OP_ISUB;
  3008.                          break;
  3009.                     case AstAssignmentExpression::LEFT_SHIFT_EQUAL:
  3010.                          opc = OP_ISHL;
  3011.                          break;
  3012.                     case AstAssignmentExpression::RIGHT_SHIFT_EQUAL:
  3013.                          opc = OP_ISHR;
  3014.                          break;
  3015.                     case AstAssignmentExpression::UNSIGNED_RIGHT_SHIFT_EQUAL:
  3016.                          opc = OP_IUSHR;
  3017.                          break;
  3018.                     case AstAssignmentExpression::AND_EQUAL:
  3019.                          opc = OP_IAND;
  3020.                          break;
  3021.                     case AstAssignmentExpression::IOR_EQUAL:
  3022.                          opc = OP_IOR;
  3023.                          break;
  3024.                     case AstAssignmentExpression::XOR_EQUAL:
  3025.                          opc = OP_IXOR;
  3026.                          break;
  3027.                     default:
  3028.                          break;
  3029.                 }
  3030.             }
  3031.             else if (op_type == this_control.long_type)
  3032.             {
  3033.                 switch (assignment_expression -> assignment_tag)
  3034.                 {
  3035.                     case AstAssignmentExpression::STAR_EQUAL:
  3036.                          opc = OP_LMUL;
  3037.                          break;
  3038.                     case AstAssignmentExpression::SLASH_EQUAL:
  3039.                          opc = OP_LDIV;
  3040.                          break;
  3041.                     case AstAssignmentExpression::MOD_EQUAL:
  3042.                          opc = OP_LREM;
  3043.                          break;
  3044.                     case AstAssignmentExpression::PLUS_EQUAL:
  3045.                          opc = OP_LADD;
  3046.                          break;
  3047.                     case AstAssignmentExpression::MINUS_EQUAL:
  3048.                          opc = OP_LSUB;
  3049.                          break;
  3050.                     case AstAssignmentExpression::LEFT_SHIFT_EQUAL:
  3051.                          opc = OP_LSHL;
  3052.                          break;
  3053.                     case AstAssignmentExpression::RIGHT_SHIFT_EQUAL:
  3054.                          opc = OP_LSHR;
  3055.                          break;
  3056.                     case AstAssignmentExpression::UNSIGNED_RIGHT_SHIFT_EQUAL:
  3057.                          opc = OP_LUSHR;
  3058.                          break;
  3059.                     case AstAssignmentExpression::AND_EQUAL:
  3060.                          opc = OP_LAND;
  3061.                          break;
  3062.                     case AstAssignmentExpression::IOR_EQUAL:
  3063.                          opc = OP_LOR;
  3064.                          break;
  3065.                     case AstAssignmentExpression::XOR_EQUAL:
  3066.                          opc = OP_LXOR;
  3067.                          break;
  3068.                     default:
  3069.                          break;
  3070.                 }
  3071.             }
  3072.             else if (op_type == this_control.float_type)
  3073.             {
  3074.                 switch (assignment_expression -> assignment_tag)
  3075.                 {
  3076.                     case AstAssignmentExpression::STAR_EQUAL:
  3077.                          opc = OP_FMUL;
  3078.                          break;
  3079.                     case AstAssignmentExpression::SLASH_EQUAL:
  3080.                          opc = OP_FDIV;
  3081.                          break;
  3082.                     case AstAssignmentExpression::MOD_EQUAL:
  3083.                          opc = OP_FREM;
  3084.                          break;
  3085.                     case AstAssignmentExpression::PLUS_EQUAL:
  3086.                          opc = OP_FADD;
  3087.                          break;
  3088.                     case AstAssignmentExpression::MINUS_EQUAL:
  3089.                          opc = OP_FSUB;
  3090.                          break;
  3091.                     default:
  3092.                          break;
  3093.                 }
  3094.             }
  3095.             else if (op_type == this_control.double_type)
  3096.             {
  3097.                 switch (assignment_expression -> assignment_tag)
  3098.                 {
  3099.                     case AstAssignmentExpression::STAR_EQUAL:
  3100.                          opc = OP_DMUL;
  3101.                          break;
  3102.                     case AstAssignmentExpression::SLASH_EQUAL:
  3103.                          opc = OP_DDIV;
  3104.                          break;
  3105.                     case AstAssignmentExpression::MOD_EQUAL:
  3106.                          opc = OP_DREM;
  3107.                          break;
  3108.                     case AstAssignmentExpression::PLUS_EQUAL:
  3109.                          opc = OP_DADD;
  3110.                          break;
  3111.                     case AstAssignmentExpression::MINUS_EQUAL:
  3112.                          opc = OP_DSUB;
  3113.                          break;
  3114.                     default:
  3115.                          break;
  3116.                 }
  3117.             }
  3118.  
  3119.             //
  3120.             // convert value to desired type if necessary
  3121.             //
  3122.             if (casted_left_hand_side)
  3123.                 EmitCast(casted_left_hand_side -> Type(), left_type);
  3124.  
  3125.             EmitExpression(assignment_expression -> expression);
  3126.  
  3127.             PutOp(opc);
  3128.  
  3129.             if (casted_left_hand_side) // now cast result back to type of result
  3130.                 EmitCast(left_type, casted_left_hand_side -> Type());
  3131.         }
  3132.     }
  3133.  
  3134.     //
  3135.     // Update left operand, saving value of right operand if it is needed.
  3136.     //
  3137.     switch(kind)
  3138.     {
  3139.         case LHS_ARRAY:
  3140.              if (need_value)
  3141.                  PutOp(this_control.IsDoubleWordType(left_type) ? OP_DUP2_X2 : OP_DUP_X2);
  3142.              StoreArrayElement(assignment_expression -> Type());
  3143.              break;
  3144.         case LHS_FIELD:
  3145.              if (need_value)
  3146.                  PutOp(this_control.IsDoubleWordType(left_type) ? OP_DUP2_X1 : OP_DUP_X1);
  3147.              StoreField(left_hand_side);
  3148.              break;
  3149.         case LHS_METHOD:
  3150.              {
  3151.                  if (need_value)
  3152.                  {
  3153.                      if (accessed_member -> ACC_STATIC())
  3154.                           PutOp(this_control.IsDoubleWordType(left_type) ? OP_DUP2 : OP_DUP);
  3155.                      else PutOp(this_control.IsDoubleWordType(left_type) ? OP_DUP2_X1 : OP_DUP_X1);
  3156.                  }
  3157.  
  3158.                  int stack_words = (this_control.IsDoubleWordType(left_type) ? 2 : 1) + (accessed_member -> ACC_STATIC() ? 0 : 1);
  3159.                  PutOp(OP_INVOKESTATIC);
  3160.                  CompleteCall(assignment_expression -> write_method, stack_words);
  3161.              }
  3162.              break;
  3163.         case LHS_LOCAL:
  3164.         case LHS_STATIC:
  3165.             if (need_value)
  3166.                 PutOp(this_control.IsDoubleWordType(left_type) ? OP_DUP2 : OP_DUP);
  3167.             StoreVariable(kind, left_hand_side);
  3168.             break;
  3169.         default:
  3170.             break;
  3171.     }
  3172.  
  3173.     if (this_control.option.g && assignment_expression -> assignment_tag == AstAssignmentExpression::DEFINITE_EQUAL)
  3174.     {
  3175.         VariableSymbol *variable = assignment_expression -> left_hand_side -> symbol -> VariableCast();
  3176.         assert(variable);
  3177. #ifdef TEST
  3178.         assert(method_stack -> StartPc(variable) == 0xFFFF); // must be uninitialized
  3179. #endif
  3180. #ifdef DUMP
  3181. Coutput << "(59) Variable \"" << variable -> Name()
  3182.         << "\" numbered " << variable -> LocalVariableIndex()
  3183.         << " was processed\n";
  3184. Coutput.flush();
  3185. #endif
  3186.         method_stack -> StartPc(variable) = code_attribute -> CodeLength();
  3187.     }
  3188.  
  3189.     return GetTypeWords(assignment_expression -> Type());
  3190. }
  3191.  
  3192.  
  3193. //
  3194. // BINARY: Similar code patterns are used for the ordered comparisons
  3195. //
  3196. int ByteCode::EmitBinaryExpression(AstBinaryExpression *expression)
  3197. {
  3198.     switch (expression -> binary_tag) // process boolean-results first
  3199.     {
  3200.         case AstBinaryExpression::OR_OR:
  3201.         case AstBinaryExpression::AND_AND:
  3202.         case AstBinaryExpression::LESS:
  3203.         case AstBinaryExpression::LESS_EQUAL:
  3204.         case AstBinaryExpression::GREATER:
  3205.         case AstBinaryExpression::GREATER_EQUAL:
  3206.         case AstBinaryExpression::EQUAL_EQUAL:
  3207.         case AstBinaryExpression::NOT_EQUAL:
  3208.              {
  3209.                  Label lab1,
  3210.                        lab2;
  3211.                  EmitBranchIfExpression(expression, true, lab1);
  3212.                  PutOp(OP_ICONST_0);                // push false
  3213.                  EmitBranch(OP_GOTO, lab2);
  3214.                  DefineLabel(lab1);
  3215.                  PutOp(OP_ICONST_1);                // push false
  3216.                  DefineLabel(lab2);
  3217.                  CompleteLabel(lab1);
  3218.                  CompleteLabel(lab2);
  3219.              }
  3220.              return 1;
  3221.         default:
  3222.              break;
  3223.     }
  3224.  
  3225.     if (expression -> binary_tag == AstBinaryExpression::INSTANCEOF)
  3226.     {
  3227.         TypeSymbol *instanceof_type = expression -> right_expression -> Type();
  3228.         EmitExpression(expression -> left_expression);
  3229.         PutOp(OP_INSTANCEOF);
  3230.         PutU2(instanceof_type -> num_dimensions > 0 ? RegisterClass(instanceof_type -> signature)
  3231.                                                     : RegisterClass(instanceof_type -> fully_qualified_name));
  3232.         return 1;
  3233.     }
  3234.  
  3235.     //
  3236.     // special case string concatenation
  3237.     //
  3238.     if (expression -> binary_tag == AstBinaryExpression::PLUS &&
  3239.         (IsReferenceType(expression -> left_expression -> Type()) || IsReferenceType(expression -> right_expression -> Type())))
  3240.     {
  3241.         ConcatenateString(expression);
  3242.         return 1;
  3243.     }
  3244.  
  3245.     //
  3246.     // Try to simplify if one operand known to be zero.
  3247.     //
  3248.     if (IsZero(expression -> left_expression))
  3249.     {
  3250.         TypeSymbol *right_type = expression -> right_expression -> Type();
  3251.         switch (expression -> binary_tag)
  3252.         {
  3253.             case AstBinaryExpression::PLUS:
  3254.             case AstBinaryExpression::IOR:
  3255.             case AstBinaryExpression::XOR:
  3256.                  EmitExpression(expression -> right_expression);
  3257.                  return GetTypeWords(expression -> Type());
  3258.             case AstBinaryExpression::STAR:
  3259.             case AstBinaryExpression::AND:
  3260.             case AstBinaryExpression::LEFT_SHIFT:
  3261.             case AstBinaryExpression::RIGHT_SHIFT:
  3262.             case AstBinaryExpression::UNSIGNED_RIGHT_SHIFT:
  3263.                  if (this_control.IsSimpleIntegerValueType(right_type) || right_type == this_control.boolean_type)
  3264.                      LoadImmediateInteger(0);
  3265.                  else
  3266.                  {
  3267.                      assert((right_type == this_control.long_type ||
  3268.                              right_type == this_control.float_type ||
  3269.                              right_type == this_control.double_type) && "unexpected type in expression simplification");
  3270.  
  3271.                      PutOp(right_type == this_control.long_type
  3272.                                        ? OP_LCONST_0
  3273.                                        : right_type == this_control.float_type
  3274.                                                      ? OP_FCONST_0
  3275.                                                      : OP_DCONST_0); // double_type
  3276.                  }
  3277.                  return GetTypeWords(right_type);
  3278.             case AstBinaryExpression::MINUS: // 0 - x is negation of x
  3279.                  EmitExpression(expression -> right_expression);
  3280.  
  3281.                  assert((this_control.IsSimpleIntegerValueType(right_type) ||
  3282.                          right_type == this_control.long_type ||
  3283.                          right_type == this_control.float_type ||
  3284.                          right_type == this_control.double_type) && "unexpected type in expression simplification");
  3285.  
  3286.                  PutOp(this_control.IsSimpleIntegerValueType(right_type)
  3287.                            ? OP_INEG
  3288.                            : right_type == this_control.long_type
  3289.                                          ? OP_LNEG
  3290.                                          : right_type == this_control.float_type
  3291.                                                        ? OP_FNEG
  3292.                                                        : OP_DNEG); // double_type
  3293.                  return GetTypeWords(expression -> Type());
  3294.             default:
  3295.                  break;
  3296.         }
  3297.     }
  3298.  
  3299.     if (IsZero(expression -> right_expression))
  3300.     {
  3301.         TypeSymbol *left_type = expression -> left_expression -> Type();
  3302.         switch (expression -> binary_tag)
  3303.         {
  3304.             case AstBinaryExpression::PLUS:
  3305.             case AstBinaryExpression::MINUS:
  3306.             case AstBinaryExpression::IOR:
  3307.             case AstBinaryExpression::XOR:
  3308.             case AstBinaryExpression::LEFT_SHIFT:
  3309.             case AstBinaryExpression::RIGHT_SHIFT:
  3310.             case AstBinaryExpression::UNSIGNED_RIGHT_SHIFT: // here for cases that simplify to the left operand
  3311.                  EmitExpression(expression -> left_expression);
  3312.                  return GetTypeWords(expression -> Type());
  3313.             case AstBinaryExpression::STAR:
  3314.             case AstBinaryExpression::AND: // here for cases that evaluate to zero
  3315.                  if (this_control.IsSimpleIntegerValueType(left_type) || left_type == this_control.boolean_type)
  3316.                       LoadImmediateInteger(0);
  3317.                  else
  3318.                  {
  3319.                      assert((left_type == this_control.long_type ||
  3320.                              left_type == this_control.float_type ||
  3321.                              left_type == this_control.double_type) && "unexpected type in expression simplification");
  3322.  
  3323.                      PutOp(left_type == this_control.long_type
  3324.                                       ? OP_LCONST_0
  3325.                                       : left_type == this_control.float_type
  3326.                                                    ? OP_FCONST_0
  3327.                                                    : OP_DCONST_0); // double_type
  3328.                  }
  3329.                  return GetTypeWords(expression -> Type());
  3330.             default:
  3331.                  break;
  3332.         }
  3333.     }
  3334.  
  3335.     EmitExpression(expression -> left_expression);
  3336.     EmitExpression(expression -> right_expression);
  3337.  
  3338.     TypeSymbol *type = expression -> left_expression -> Type();
  3339.     bool integer_type = (this_control.IsSimpleIntegerValueType(type) || type == this_control.boolean_type);
  3340.     switch (expression -> binary_tag)
  3341.     {
  3342.         case AstBinaryExpression::STAR:
  3343.              PutOp(integer_type ? OP_IMUL
  3344.                                 : type == this_control.long_type
  3345.                                         ? OP_LMUL
  3346.                                         : type == this_control.float_type
  3347.                                                 ? OP_FMUL
  3348.                                                 : OP_DMUL); // double_type
  3349.              break;
  3350.         case AstBinaryExpression::SLASH:
  3351.              PutOp(integer_type ? OP_IDIV
  3352.                                 : type == this_control.long_type
  3353.                                         ? OP_LDIV
  3354.                                         : type == this_control.float_type
  3355.                                                 ? OP_FDIV
  3356.                                                 : OP_DDIV); // double_type
  3357.              break;
  3358.         case AstBinaryExpression::MOD:
  3359.              PutOp(integer_type ? OP_IREM
  3360.                                 : type == this_control.long_type
  3361.                                         ? OP_LREM
  3362.                                         : type == this_control.float_type
  3363.                                                 ? OP_FREM
  3364.                                                 : OP_DREM); // double_type
  3365.              break;
  3366.         case AstBinaryExpression::PLUS:
  3367.              PutOp(integer_type ? OP_IADD
  3368.                                 : type == this_control.long_type
  3369.                                         ? OP_LADD
  3370.                                         : type == this_control.float_type
  3371.                                                 ? OP_FADD
  3372.                                                 : OP_DADD); // double_type
  3373.              break;
  3374.         case AstBinaryExpression::MINUS:
  3375.              PutOp(integer_type ? OP_ISUB
  3376.                                 : type == this_control.long_type
  3377.                                         ? OP_LSUB
  3378.                                         : type == this_control.float_type
  3379.                                                 ? OP_FSUB
  3380.                                                 : OP_DSUB); // double_type
  3381.              break;
  3382.         case AstBinaryExpression::LEFT_SHIFT:
  3383.              PutOp(integer_type ? OP_ISHL : OP_LSHL);
  3384.              break;
  3385.         case AstBinaryExpression::RIGHT_SHIFT:
  3386.              PutOp(integer_type ? OP_ISHR : OP_LSHR);
  3387.              break;
  3388.         case AstBinaryExpression::UNSIGNED_RIGHT_SHIFT:
  3389.              PutOp(integer_type ? OP_IUSHR : OP_LUSHR);
  3390.              break;
  3391.         case AstBinaryExpression::AND:
  3392.              PutOp(integer_type ? OP_IAND : OP_LAND);
  3393.              break;
  3394.         case AstBinaryExpression::XOR:
  3395.              PutOp(integer_type ? OP_IXOR : OP_LXOR);
  3396.              break;
  3397.         case AstBinaryExpression::IOR:
  3398.              PutOp(integer_type ? OP_IOR : OP_LOR);
  3399.              break;
  3400.         default:
  3401.              assert(false && "binary unknown tag");
  3402.     }
  3403.  
  3404.     return GetTypeWords(expression -> Type());
  3405. }
  3406.  
  3407.  
  3408. int ByteCode::EmitCastExpression(AstCastExpression *expression)
  3409. {
  3410.     //
  3411.     // convert from numeric type src to destination type dest
  3412.     //
  3413.     EmitExpression(expression -> expression);
  3414.  
  3415.     TypeSymbol *dest_type = expression -> Type(),
  3416.                *source_type = expression -> expression -> Type();
  3417.     EmitCast(dest_type, source_type);
  3418.  
  3419.     return GetTypeWords(dest_type);
  3420. }
  3421.  
  3422.  
  3423. void ByteCode::EmitCast(TypeSymbol *dest_type, TypeSymbol *source_type)
  3424. {
  3425.     if (dest_type == source_type) // done if nothing to do
  3426.         return;
  3427.  
  3428.     if (this_control.IsSimpleIntegerValueType(source_type))
  3429.     {
  3430.         if (dest_type != this_control.int_type) // no conversion needed
  3431.         {
  3432.             Operators::operators op_kind = (dest_type == this_control.long_type
  3433.                                                        ? OP_I2L
  3434.                                                        : dest_type == this_control.float_type
  3435.                                                                     ? OP_I2F
  3436.                                                                     : dest_type == this_control.double_type
  3437.                                                                                  ? OP_I2D
  3438.                                                                                  : dest_type == this_control.char_type
  3439.                                                                                               ? OP_I2C
  3440.                                                                                               : dest_type == this_control.byte_type
  3441.                                                                                                            ? OP_I2B
  3442.                                                                                                            : OP_I2S); // short_type
  3443.             assert(op_kind != OP_I2S || dest_type == this_control.short_type);
  3444.  
  3445.             PutOp(op_kind);
  3446.         }
  3447.     }
  3448.     else if (source_type == this_control.long_type)
  3449.     {
  3450.         Operators::operators op_kind = (dest_type == this_control.float_type
  3451.                                                    ? OP_L2F
  3452.                                                    : dest_type == this_control.double_type
  3453.                                                                 ? OP_L2D
  3454.                                                                 : OP_L2I);
  3455.         PutOp(op_kind);
  3456.  
  3457.         if (op_kind == OP_L2I && dest_type != this_control.int_type)
  3458.         {
  3459.             assert(this_control.IsSimpleIntegerValueType(dest_type) && "unsupported conversion");
  3460.  
  3461.             PutOp(dest_type == this_control.char_type
  3462.                              ? OP_I2C
  3463.                              : dest_type == this_control.byte_type
  3464.                                           ? OP_I2B
  3465.                                           : OP_I2S); // short_type
  3466.         }
  3467.     }
  3468.     else if (source_type == this_control.float_type)
  3469.     {
  3470.         Operators::operators op_kind = (dest_type == this_control.long_type
  3471.                                                    ? OP_F2L
  3472.                                                    : dest_type == this_control.double_type
  3473.                                                                 ? OP_F2D
  3474.                                                                 : OP_F2I);
  3475.         PutOp(op_kind);
  3476.  
  3477.         if (op_kind == OP_F2I && dest_type != this_control.int_type)
  3478.         {
  3479.             assert(this_control.IsSimpleIntegerValueType(dest_type) && "unsupported conversion");
  3480.  
  3481.             PutOp(dest_type == this_control.char_type
  3482.                              ? OP_I2C
  3483.                              : dest_type == this_control.byte_type
  3484.                                           ? OP_I2B
  3485.                                           : OP_I2S); // short_type
  3486.         }
  3487.     }
  3488.     else if (source_type == this_control.double_type)
  3489.     {
  3490.         Operators::operators op_kind = (dest_type == this_control.long_type
  3491.                                                    ? OP_D2L
  3492.                                                    : dest_type == this_control.float_type
  3493.                                                                 ? OP_D2F
  3494.                                                                 : OP_D2I);
  3495.  
  3496.         PutOp(op_kind);
  3497.  
  3498.         if (op_kind == OP_D2I && dest_type != this_control.int_type)
  3499.         {
  3500.             assert(this_control.IsSimpleIntegerValueType(dest_type) && "unsupported conversion");
  3501.  
  3502.             PutOp(dest_type == this_control.char_type
  3503.                              ? OP_I2C
  3504.                              : dest_type == this_control.byte_type
  3505.                                           ? OP_I2B
  3506.                                           : OP_I2S); // short_type
  3507.         }
  3508.     }
  3509.     else if (source_type == this_control.null_type)
  3510.          ; // Nothing to do
  3511.     else
  3512.     {
  3513.         //
  3514.         // Generate check cast instruction.
  3515.         //
  3516.         PutOp(OP_CHECKCAST);
  3517.         PutU2(dest_type -> num_dimensions > 0 ? RegisterClass(dest_type -> signature)
  3518.                                               : RegisterClass(dest_type -> fully_qualified_name));
  3519.     }
  3520.  
  3521.     return;
  3522. }
  3523.  
  3524.  
  3525. int ByteCode::EmitClassInstanceCreationExpression(AstClassInstanceCreationExpression *expression, bool need_value)
  3526. {
  3527.     MethodSymbol *constructor = (MethodSymbol *) expression -> class_type -> symbol;
  3528.  
  3529.     PutOp(OP_NEW);
  3530.     PutU2(RegisterClass(expression -> Type() -> fully_qualified_name));
  3531.     if (need_value) // save address of new object for constructor
  3532.         PutOp(OP_DUP);
  3533.  
  3534.     //
  3535.     // call constructor
  3536.     // pass address of object explicitly passed to new if specified.
  3537.     //
  3538.     int stack_words = 0;
  3539.     if (expression -> base_opt)
  3540.     {
  3541.         stack_words += EmitExpression(expression -> base_opt);
  3542.         PutOp(OP_DUP);
  3543.  
  3544.         Label lab1;
  3545.         EmitBranch(OP_IFNONNULL, lab1);
  3546.         PutOp(OP_ACONST_NULL); // need to test for null, raising NullPointerException if so. So just do athrow
  3547.         PutOp(OP_ATHROW);
  3548.         DefineLabel(lab1);
  3549.         CompleteLabel(lab1);
  3550.     }
  3551.  
  3552.     //
  3553.     // Pass all local arguments, if any
  3554.     //
  3555.     for (int i = 0; i < expression -> NumLocalArguments(); i++)
  3556.         stack_words += EmitExpression((AstExpression *) expression -> LocalArgument(i));
  3557.  
  3558.     //
  3559.     // If we are calling a private constructor, pass the extra null argument to the access constructor.
  3560.     //
  3561.     if (expression -> NeedsExtraNullArgument())
  3562.     {
  3563.         PutOp(OP_ACONST_NULL);
  3564.         stack_words += 1;
  3565.     }
  3566.  
  3567.     //
  3568.     // Now, process the real arguments specified in the source.
  3569.     //
  3570.     for (int k = 0; k < expression -> NumArguments(); k++)
  3571.         stack_words += EmitExpression((AstExpression *) expression -> Argument(k));
  3572.  
  3573.     PutOp(OP_INVOKENONVIRTUAL);
  3574.     ChangeStack(-stack_words);
  3575.     PutU2(RegisterMethodref(expression -> Type() -> fully_qualified_name,
  3576.                             this_control.init_name_symbol -> Utf8_literal,
  3577.                             constructor -> signature));
  3578.  
  3579.     return 1;
  3580. }
  3581.  
  3582.  
  3583. int ByteCode::EmitConditionalExpression(AstConditionalExpression *expression)
  3584. {
  3585.     Label lab1,
  3586.           lab2;
  3587.     EmitBranchIfExpression(expression -> test_expression, false, lab1);
  3588.     EmitExpression(expression -> true_expression);
  3589.     EmitBranch(OP_GOTO, lab2);
  3590.     DefineLabel(lab1);
  3591.     EmitExpression(expression -> false_expression);
  3592.     DefineLabel(lab2);
  3593.     CompleteLabel(lab1);
  3594.     CompleteLabel(lab2);
  3595.  
  3596.     return GetTypeWords(expression -> true_expression -> Type());
  3597. }
  3598.  
  3599.  
  3600. int ByteCode::EmitFieldAccess(AstFieldAccess *expression)
  3601. {
  3602.     assert(! expression -> IsConstant());
  3603.  
  3604.     AstExpression *base = expression -> base;
  3605.     VariableSymbol *sym = expression -> symbol -> VariableCast();
  3606.  
  3607.     if (expression -> resolution_opt) // resolve reference to private field in parent
  3608.         return EmitExpression(expression -> resolution_opt);
  3609.  
  3610.     if (base -> Type() -> IsArray() && sym -> ExternalIdentity() == this_control.length_name_symbol)
  3611.     {
  3612.         EmitExpression(base);
  3613.         PutOp(OP_ARRAYLENGTH);
  3614.  
  3615.         return 1;
  3616.     }
  3617.  
  3618.     TypeSymbol *expression_type = expression -> Type();
  3619.     if (sym -> ACC_STATIC())
  3620.     {
  3621.         if (! base -> IsSimpleNameOrFieldAccess()) // if the base expression is an arbitrary expression, evaluate it for side effects.
  3622.         {
  3623.             EmitExpression(base);
  3624.             PutOp(OP_POP);
  3625.         }
  3626.         PutOp(OP_GETSTATIC);
  3627.         ChangeStack(this_control.IsDoubleWordType(expression_type) ? 2 : 1);
  3628.     }
  3629.     else
  3630.     {
  3631.         EmitExpression(base); // get base
  3632.         PutOp(OP_GETFIELD);
  3633.         ChangeStack(this_control.IsDoubleWordType(expression_type) ? 1 : 0);
  3634.     }
  3635.  
  3636.     PutU2(RegisterFieldref(VariableTypeResolution(expression, sym), sym));
  3637.  
  3638.     return GetTypeWords(expression_type);
  3639. }
  3640.  
  3641.  
  3642. void ByteCode::EmitMethodInvocation(AstMethodInvocation *expression)
  3643. {
  3644.     //
  3645.     // If the method call was resolved into a call to another method, use the resolution expression.
  3646.     //
  3647.     AstMethodInvocation *method_call = (expression -> resolution_opt
  3648.                                                     ? expression -> resolution_opt -> MethodInvocationCast()
  3649.                                                     : expression);
  3650.  
  3651.     MethodSymbol *msym = (MethodSymbol *) method_call -> symbol;
  3652.  
  3653.     bool is_super = false; // set if super call
  3654.  
  3655.     AstFieldAccess *field = method_call -> method -> FieldAccessCast();
  3656.     AstSimpleName *simple_name = method_call -> method -> SimpleNameCast();
  3657.     if (msym -> ACC_STATIC())
  3658.     {
  3659.         if (field)
  3660.         {
  3661.             if (field -> base -> MethodInvocationCast())
  3662.             {
  3663.                 EmitMethodInvocation(field -> base -> MethodInvocationCast());
  3664.                 PutOp(OP_POP); // discard value (only evaluating for side effect)
  3665.             }
  3666.             else if (field -> base -> ClassInstanceCreationExpressionCast())
  3667.             {
  3668.                 (void) EmitClassInstanceCreationExpression(field -> base -> ClassInstanceCreationExpressionCast(), false);
  3669.             }
  3670.         }
  3671.     }
  3672.     else
  3673.     {
  3674.         if (field)
  3675.         {
  3676.             AstFieldAccess *sub_field_access = field -> base -> FieldAccessCast();
  3677.             is_super = field -> base -> SuperExpressionCast() || (sub_field_access && sub_field_access -> IsSuperAccess());
  3678.  
  3679.             if (field -> base -> MethodInvocationCast())
  3680.                  EmitMethodInvocation(field -> base -> MethodInvocationCast());
  3681.             else EmitExpression(field -> base);
  3682.         }
  3683.         else if (method_call -> method -> SimpleNameCast())
  3684.         {
  3685.             if (simple_name -> resolution_opt) // use resolution if available
  3686.                 EmitExpression(simple_name -> resolution_opt);
  3687.             else // must be field of current object, so load this
  3688.                 PutOp(OP_ALOAD_0);
  3689.         }
  3690.         else assert(false && "unexpected argument to field access");
  3691.     }
  3692.  
  3693.     int stack_words = 0; // words on stack needed for arguments
  3694.     for (int i = 0; i < method_call -> NumArguments(); i++)
  3695.         stack_words += EmitExpression((AstExpression *) method_call -> Argument(i));
  3696.  
  3697.     TypeSymbol *type = MethodTypeResolution(method_call -> method, msym);
  3698.     PutOp(msym -> ACC_STATIC()
  3699.                 ? OP_INVOKESTATIC
  3700.                 : (is_super || msym -> ACC_PRIVATE())
  3701.                              ? OP_INVOKENONVIRTUAL
  3702.                              : type -> ACC_INTERFACE() ? OP_INVOKEINTERFACE : OP_INVOKEVIRTUAL);
  3703.     CompleteCall(msym, stack_words, type);
  3704.  
  3705.     return;
  3706. }
  3707.  
  3708.  
  3709. void ByteCode::CompleteCall(MethodSymbol *msym, int stack_words, TypeSymbol *base_type)
  3710. {
  3711.     ChangeStack(-stack_words);
  3712.  
  3713.     TypeSymbol *type = (base_type ? base_type : msym -> containing_type);
  3714.  
  3715.     PutU2(type -> ACC_INTERFACE() ? RegisterInterfaceMethodref(type -> fully_qualified_name,
  3716.                                                                msym -> ExternalIdentity() -> Utf8_literal,
  3717.                                                                msym -> signature)
  3718.                                   : RegisterMethodref(type -> fully_qualified_name,
  3719.                                                       msym -> ExternalIdentity() -> Utf8_literal,
  3720.                                                       msym -> signature));
  3721.  
  3722.     if (type -> ACC_INTERFACE())
  3723.     {
  3724.         PutU1(stack_words + 1);
  3725.         PutU1(0);
  3726.     }
  3727.  
  3728.     //
  3729.     // must account for value returned by method.
  3730.     //
  3731.     ChangeStack(this_control.IsDoubleWordType(msym -> Type()) ? 2 : msym -> Type() == this_control.void_type ? 0 : 1);
  3732.  
  3733.     return;
  3734. }
  3735.  
  3736.  
  3737. void ByteCode::EmitNewArray(int num_dims, TypeSymbol *type)
  3738. {
  3739.     if (num_dims == 0 || (num_dims == 1 && type -> num_dimensions == num_dims))
  3740.     {
  3741.         TypeSymbol *element_type = type -> ArraySubtype();
  3742.  
  3743.         if (this_control.IsNumeric(element_type) || element_type == this_control.boolean_type) // one-dimensional primitive?
  3744.         {
  3745.             PutOp(OP_NEWARRAY);
  3746.             PutU1(element_type == this_control.boolean_type
  3747.                          ? 4
  3748.                          : element_type == this_control.char_type
  3749.                                   ? 5
  3750.                                   : element_type == this_control.float_type
  3751.                                            ? 6
  3752.                                            : element_type == this_control.double_type
  3753.                                                     ? 7
  3754.                                                     : element_type == this_control.byte_type
  3755.                                                              ? 8
  3756.                                                              : element_type == this_control.short_type
  3757.                                                                       ? 9
  3758.                                                                       : element_type == this_control.int_type
  3759.                                                                                ? 10
  3760.                                                                                : 11); // control.long_type
  3761.         }
  3762.         else // must be reference type
  3763.         {
  3764.             PutOp(OP_ANEWARRAY);
  3765.             PutU2(RegisterClass(element_type -> fully_qualified_name));
  3766.         }
  3767.     }
  3768.     else
  3769.     {
  3770.         PutOp(OP_MULTIANEWARRAY);
  3771.         PutU2(RegisterClass(type -> signature));
  3772.         PutU1(num_dims); // load dims count
  3773.         ChangeStack(num_dims - 1);
  3774.     }
  3775.  
  3776.     return;
  3777. }
  3778.  
  3779.  
  3780. //
  3781. // POST_UNARY
  3782. //
  3783. int ByteCode::EmitPostUnaryExpression(AstPostUnaryExpression *expression, bool need_value)
  3784. {
  3785.     int kind = GetLhsKind(expression);
  3786.  
  3787.     switch(kind)
  3788.     {
  3789.         case LHS_LOCAL:
  3790.         case LHS_STATIC:
  3791.              EmitPostUnaryExpressionSimple(kind, expression, need_value);
  3792.              break;
  3793.         case LHS_ARRAY:
  3794.              EmitPostUnaryExpressionArray(expression, need_value);
  3795.              break;
  3796.         case LHS_FIELD:
  3797.              EmitPostUnaryExpressionField(kind, expression, need_value);
  3798.              break;
  3799.         case LHS_METHOD:
  3800.              {
  3801.                  VariableSymbol *accessed_member = expression -> write_method -> accessed_member -> VariableCast();
  3802.                  if (accessed_member -> ACC_STATIC())
  3803.                       EmitPostUnaryExpressionSimple(kind, expression, need_value);
  3804.                  else EmitPostUnaryExpressionField(kind, expression, need_value);
  3805.              }
  3806.              break;
  3807.         default:
  3808.              assert(false && "unknown lhs kind for assignment");
  3809.     }
  3810.  
  3811.     return GetTypeWords(expression -> Type());
  3812. }
  3813.  
  3814.  
  3815. //
  3816. // AstExpression *expression;
  3817. // POST_UNARY on instance variable
  3818. // load value of field, duplicate, do increment or decrement, then store back, leaving original value
  3819. // on top of stack.
  3820. //
  3821. void ByteCode::EmitPostUnaryExpressionField(int kind, AstPostUnaryExpression *expression, bool need_value)
  3822. {
  3823.     if (kind == LHS_METHOD)
  3824.          ResolveAccess(expression -> expression); // get address and value
  3825.     else EmitFieldAccessLhs(expression -> expression);
  3826.  
  3827.     TypeSymbol *expression_type = expression -> Type();
  3828.     if (need_value)
  3829.         PutOp(this_control.IsDoubleWordType(expression_type) ? OP_DUP2_X1 : OP_DUP_X1);
  3830.  
  3831.     if (this_control.IsSimpleIntegerValueType(expression_type))
  3832.     {
  3833.         PutOp(OP_ICONST_1);
  3834.         PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  3835.     }
  3836.     else if (expression_type == this_control.long_type)
  3837.     {
  3838.         PutOp(OP_LCONST_1);
  3839.         PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_LADD : OP_LSUB);
  3840.     }
  3841.     else if (expression_type == this_control.float_type)
  3842.     {
  3843.         PutOp(OP_FCONST_1);
  3844.         PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_FADD : OP_FSUB);
  3845.     }
  3846.     else if (expression_type == this_control.double_type)
  3847.     {
  3848.         PutOp(OP_DCONST_1); // load 1.0
  3849.         PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_DADD : OP_DSUB);
  3850.     }
  3851.  
  3852.     if (kind == LHS_METHOD)
  3853.     {
  3854.         int stack_words = (this_control.IsDoubleWordType(expression_type) ? 2 : 1) + 1;
  3855.         PutOp(OP_INVOKESTATIC);
  3856.         CompleteCall(expression -> write_method, stack_words);
  3857.     }
  3858.     else // assert(kind == LHS_FIELD)
  3859.     {
  3860.         PutOp(OP_PUTFIELD);
  3861.         ChangeStack(this_control.IsDoubleWordType(expression_type) ? -3 : -2);
  3862.  
  3863.         VariableSymbol *sym = (VariableSymbol *) expression -> symbol;
  3864.         PutU2(RegisterFieldref(VariableTypeResolution(expression -> expression, sym), sym));
  3865.     }
  3866.  
  3867.     return;
  3868. }
  3869.  
  3870.  
  3871. //
  3872. // AstExpression *expression;
  3873. // POST_UNARY on local variable
  3874. // load value of variable, duplicate, do increment or decrement, then store back, leaving original value
  3875. // on top of stack.
  3876. //
  3877. void ByteCode::EmitPostUnaryExpressionSimple(int kind, AstPostUnaryExpression *expression, bool need_value)
  3878. {
  3879.     TypeSymbol *expression_type = expression -> Type();
  3880.     if (kind == LHS_LOCAL && expression_type == this_control.int_type) // can we use IINC ??
  3881.     {
  3882.         if (need_value)
  3883.             (void) LoadVariable(kind, expression);
  3884.         PutOpIINC(expression -> symbol -> VariableCast() -> LocalVariableIndex(),
  3885.                   expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? 1 : -1);
  3886.         return;
  3887.     }
  3888.  
  3889.     (void) LoadVariable(kind, expression -> expression); // this will also load value needing resolution
  3890.  
  3891.     if (need_value)
  3892.         PutOp(this_control.IsDoubleWordType(expression_type) ? OP_DUP2 : OP_DUP);
  3893.  
  3894.     if (this_control.IsSimpleIntegerValueType(expression_type))
  3895.     {
  3896.         PutOp(OP_ICONST_1);
  3897.         PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  3898.         EmitCast(expression_type, this_control.int_type);
  3899.     }
  3900.     else if (expression_type == this_control.long_type)
  3901.     {
  3902.         PutOp(OP_LCONST_1);
  3903.         PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_LADD : OP_LSUB);
  3904.     }
  3905.     else if (expression_type == this_control.float_type)
  3906.     {
  3907.         PutOp(OP_FCONST_1);
  3908.         PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_FADD : OP_FSUB);
  3909.     }
  3910.     else if (expression_type == this_control.double_type)
  3911.     {
  3912.         PutOp(OP_DCONST_1); // load 1.0
  3913.         PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_DADD : OP_DSUB);
  3914.     }
  3915.  
  3916.     if (kind == LHS_METHOD)
  3917.     {
  3918.          int stack_words = this_control.IsDoubleWordType(expression_type) ? 2 : 1;
  3919.          PutOp(OP_INVOKESTATIC);
  3920.          CompleteCall(expression -> write_method, stack_words);
  3921.     }
  3922.     else StoreVariable(kind, expression -> expression);
  3923.  
  3924.     return;
  3925. }
  3926.  
  3927.  
  3928. //
  3929. // Post Unary for which operand is array element
  3930. // assignment for which lhs is array element
  3931. //    AstExpression *expression;
  3932. //
  3933. void ByteCode::EmitPostUnaryExpressionArray(AstPostUnaryExpression *expression, bool need_value)
  3934. {
  3935.     EmitArrayAccessLhs((AstArrayAccess *) expression -> expression); // lhs must be array access
  3936.     PutOp(OP_DUP2); // save array base and index for later store
  3937.  
  3938.     TypeSymbol *expression_type = expression -> Type();
  3939.     if (expression_type == this_control.int_type)
  3940.     {
  3941.          PutOp(OP_IALOAD);
  3942.          if (need_value) // save value below saved array base and index
  3943.              PutOp(OP_DUP_X2);
  3944.          PutOp(OP_ICONST_1);
  3945.          PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  3946.          PutOp(OP_IASTORE);
  3947.     }
  3948.     else if (expression_type == this_control.byte_type )
  3949.     {
  3950.          PutOp(OP_BALOAD);
  3951.          if (need_value) // save value below saved array base and index
  3952.              PutOp(OP_DUP_X2);
  3953.          PutOp(OP_ICONST_1);
  3954.          PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  3955.          PutOp(OP_I2B);
  3956.          PutOp(OP_BASTORE);
  3957.     }
  3958.     else if (expression_type == this_control.char_type )
  3959.     {
  3960.          PutOp(OP_CALOAD);
  3961.          if (need_value) // save value below saved array base and index
  3962.              PutOp(OP_DUP_X2);
  3963.          PutOp(OP_ICONST_1);
  3964.          PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  3965.          PutOp(OP_I2C);
  3966.          PutOp(OP_CASTORE);
  3967.     }
  3968.     else if (expression_type == this_control.short_type)
  3969.     {
  3970.          PutOp(OP_SALOAD);
  3971.          if (need_value) // save value below saved array base and index
  3972.              PutOp(OP_DUP_X2);
  3973.          PutOp(OP_ICONST_1);
  3974.          PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  3975.          PutOp(OP_I2S);
  3976.          PutOp(OP_SASTORE);
  3977.     }
  3978.     else if (expression_type == this_control.long_type)
  3979.     {
  3980.          PutOp(OP_LALOAD);
  3981.          if (need_value) // save value below saved array base and index
  3982.              PutOp(OP_DUP2_X2);
  3983.          PutOp(OP_LCONST_1);
  3984.          PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_LADD : OP_LSUB);
  3985.          PutOp(OP_LASTORE);
  3986.     }
  3987.     else if (expression_type == this_control.float_type)
  3988.     {
  3989.          PutOp(OP_FALOAD);
  3990.          if (need_value) // save value below saved array base and index
  3991.              PutOp(OP_DUP_X2);
  3992.          PutOp(OP_FCONST_1);
  3993.          PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_FADD : OP_FSUB);
  3994.          PutOp(OP_FASTORE);
  3995.     }
  3996.     else if (expression_type == this_control.double_type)
  3997.     {
  3998.          PutOp(OP_DALOAD);
  3999.          if (need_value) // save value below saved array base and index
  4000.              PutOp(OP_DUP2_X2);
  4001.          PutOp(OP_DCONST_1);
  4002.          PutOp(expression -> post_unary_tag == AstPostUnaryExpression::PLUSPLUS ? OP_DADD : OP_DSUB);
  4003.          PutOp(OP_DASTORE);
  4004.     }
  4005.     else assert(false && "unsupported postunary type");
  4006.  
  4007.     return;
  4008. }
  4009.  
  4010.  
  4011. //
  4012. // PRE_UNARY
  4013. //
  4014. int ByteCode::EmitPreUnaryExpression(AstPreUnaryExpression *expression, bool need_value)
  4015. {
  4016.     TypeSymbol *type = expression -> Type();
  4017.     if (expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ||
  4018.         expression -> pre_unary_tag == AstPreUnaryExpression::MINUSMINUS)
  4019.     {
  4020.         EmitPreUnaryIncrementExpression(expression, need_value);
  4021.     }
  4022.     else // here for ordinary unary operator without side effects.
  4023.     {
  4024.         switch (expression -> pre_unary_tag)
  4025.         {
  4026.             case AstPreUnaryExpression::PLUS:
  4027.                  // nothing to do (front-end will have done any needed conversions)
  4028.                  EmitExpression(expression -> expression);
  4029.                  break;
  4030.             case AstPreUnaryExpression::MINUS:
  4031.                  EmitExpression(expression -> expression);
  4032.  
  4033.                  assert((this_control.IsSimpleIntegerValueType(type) ||
  4034.                          type == this_control.long_type ||
  4035.                          type == this_control.float_type ||
  4036.                          type == this_control.double_type) && "unary minus on unsupported type");
  4037.  
  4038.                  PutOp(this_control.IsSimpleIntegerValueType(type)
  4039.                            ? OP_INEG
  4040.                            : type == this_control.long_type
  4041.                                    ? OP_LNEG
  4042.                                    : type == this_control.float_type
  4043.                                            ? OP_FNEG
  4044.                                            : OP_DNEG); // double_type
  4045.                  break;
  4046.             case AstPreUnaryExpression::TWIDDLE:
  4047.                  if (this_control.IsSimpleIntegerValueType(type))
  4048.                  {
  4049.                      EmitExpression(expression -> expression);
  4050.                      PutOp(OP_ICONST_M1); // -1
  4051.                      PutOp(OP_IXOR);      // exclusive or to get result
  4052.                  }
  4053.                  else if (type == this_control.long_type)
  4054.                  {
  4055.                      EmitExpression(expression -> expression);
  4056.                      PutOp(OP_LCONST_1); // make -1
  4057.                      PutOp(OP_LNEG);
  4058.                      PutOp(OP_LXOR);     // exclusive or to get result
  4059.                  }
  4060.                  else assert(false && "unary ~ on unsupported type");
  4061.                  break;
  4062.             case AstPreUnaryExpression::NOT:
  4063.                 assert(type == this_control.boolean_type);
  4064.  
  4065.                 {
  4066.                     Label lab1,
  4067.                           lab2;
  4068.                     EmitExpression(expression -> expression);
  4069.                     EmitBranch(OP_IFEQ, lab1);
  4070.                     PutOp(OP_ICONST_0);       // turn true into false
  4071.                     EmitBranch(OP_GOTO, lab2);
  4072.                     DefineLabel(lab1);
  4073.                     PutOp(OP_ICONST_1);       // here to turn false into true
  4074.                     DefineLabel(lab2);
  4075.                     CompleteLabel(lab1);
  4076.                     CompleteLabel(lab2);
  4077.                 }
  4078.                 break;
  4079.             default:
  4080.                 assert(false && "unknown preunary tag");
  4081.         }
  4082.     }
  4083.  
  4084.     return GetTypeWords(type);
  4085. }
  4086.  
  4087.  
  4088. //
  4089. // PRE_UNARY with side effects (++X or --X)
  4090. //
  4091. void ByteCode::EmitPreUnaryIncrementExpression(AstPreUnaryExpression *expression, bool need_value)
  4092. {
  4093.     int kind = GetLhsKind(expression);
  4094.  
  4095.     switch(kind)
  4096.     {
  4097.         case LHS_LOCAL:
  4098.         case LHS_STATIC:
  4099.              EmitPreUnaryIncrementExpressionSimple(kind, expression, need_value);
  4100.              break;
  4101.         case LHS_ARRAY:
  4102.              EmitPreUnaryIncrementExpressionArray(expression, need_value);
  4103.              break;
  4104.         case LHS_FIELD:
  4105.              EmitPreUnaryIncrementExpressionField(kind, expression, need_value);
  4106.              break;
  4107.         case LHS_METHOD:
  4108.              {
  4109.                  VariableSymbol *accessed_member = expression -> write_method -> accessed_member -> VariableCast();
  4110.                  if (accessed_member -> ACC_STATIC())
  4111.                       EmitPreUnaryIncrementExpressionSimple(kind, expression, need_value);
  4112.                  else EmitPreUnaryIncrementExpressionField(kind, expression, need_value);
  4113.              }
  4114.              break;
  4115.         default:
  4116.              assert(false && "unknown lhs kind for assignment");
  4117.     }
  4118.  
  4119.     return;
  4120. }
  4121.  
  4122.  
  4123. //
  4124. //    AstExpression *expression;
  4125. // POST_UNARY on name
  4126. // load value of variable, do increment or decrement, duplicate, then store back, leaving original value
  4127. // on top of stack.
  4128. //
  4129. void ByteCode::EmitPreUnaryIncrementExpressionSimple(int kind, AstPreUnaryExpression *expression, bool need_value)
  4130. {
  4131.     TypeSymbol *type = expression -> Type();
  4132.     if (kind == LHS_LOCAL && type == this_control.int_type)
  4133.     {
  4134.         PutOpIINC(expression -> symbol -> VariableCast() -> LocalVariableIndex(),
  4135.                   expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? 1 : -1);
  4136.         if (need_value)
  4137.             (void) LoadVariable(kind, expression);
  4138.         return;
  4139.     }
  4140.  
  4141.     (void) LoadVariable(kind, expression -> expression); // will also load value if resolution needed
  4142.  
  4143.     if (this_control.IsSimpleIntegerValueType(type))
  4144.     {
  4145.         PutOp(OP_ICONST_1);
  4146.         PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  4147.         EmitCast(type, this_control.int_type);
  4148.         if (need_value)
  4149.             PutOp(OP_DUP);
  4150.     }
  4151.     else if (type == this_control.long_type)
  4152.     {
  4153.         PutOp(OP_LCONST_1);
  4154.         PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_LADD : OP_LSUB);
  4155.         if (need_value)
  4156.             PutOp(OP_DUP2);
  4157.     }
  4158.     else if (type == this_control.float_type)
  4159.     {
  4160.         PutOp(OP_FCONST_1);
  4161.         PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_FADD : OP_FSUB);
  4162.         if (need_value)
  4163.             PutOp(OP_DUP);
  4164.     }
  4165.     else if (type == this_control.double_type)
  4166.     {
  4167.         PutOp(OP_DCONST_1); // load 1.0
  4168.         PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_DADD : OP_DSUB);
  4169.         if (need_value)
  4170.             PutOp(OP_DUP2);
  4171.     }
  4172.  
  4173.     if (kind == LHS_METHOD)
  4174.     {
  4175.         int stack_words = this_control.IsDoubleWordType(type) ? 2 : 1;
  4176.         PutOp(OP_INVOKESTATIC);
  4177.         CompleteCall(expression -> write_method, stack_words);
  4178.     }
  4179.     else StoreVariable(kind, expression -> expression);
  4180.  
  4181.     return;
  4182. }
  4183.  
  4184.  
  4185. //
  4186. // Post Unary for which operand is array element
  4187. // assignment for which lhs is array element
  4188. //    AstExpression *expression;
  4189. //
  4190. void ByteCode::EmitPreUnaryIncrementExpressionArray(AstPreUnaryExpression *expression, bool need_value)
  4191. {
  4192.     EmitArrayAccessLhs((AstArrayAccess *) expression -> expression); // lhs must be array access
  4193.  
  4194.     PutOp(OP_DUP2); // save array base and index for later store
  4195.  
  4196.     TypeSymbol *type = expression -> Type();
  4197.     if (type == this_control.int_type)
  4198.     {
  4199.          PutOp(OP_IALOAD);
  4200.          PutOp(OP_ICONST_1);
  4201.          PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  4202.          if (need_value)
  4203.              PutOp(OP_DUP_X2);
  4204.          PutOp(OP_IASTORE);
  4205.     }
  4206.     else if (type == this_control.byte_type)
  4207.     {
  4208.          PutOp(OP_BALOAD);
  4209.          PutOp(OP_ICONST_1);
  4210.          PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  4211.          if (need_value)
  4212.              PutOp(OP_DUP_X2);
  4213.          PutOp(OP_I2B);
  4214.          PutOp(OP_BASTORE);
  4215.     }
  4216.     else if (type == this_control.char_type)
  4217.     {
  4218.          PutOp(OP_CALOAD);
  4219.          PutOp(OP_ICONST_1);
  4220.          PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  4221.          if (need_value)
  4222.              PutOp(OP_DUP_X2);
  4223.          PutOp(OP_I2C);
  4224.          PutOp(OP_CASTORE);
  4225.     }
  4226.     else if (type == this_control.short_type)
  4227.     {
  4228.          PutOp(OP_SALOAD);
  4229.          PutOp(OP_ICONST_1);
  4230.          PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  4231.          if (need_value)
  4232.              PutOp(OP_DUP_X2);
  4233.          PutOp(OP_I2S);
  4234.          PutOp(OP_SASTORE);
  4235.     }
  4236.     else if (type == this_control.long_type)
  4237.     {
  4238.          PutOp(OP_LALOAD);
  4239.          PutOp(OP_LCONST_1);
  4240.          PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_LADD : OP_LSUB);
  4241.          if (need_value)
  4242.              PutOp(OP_DUP2_X2);
  4243.          PutOp(OP_LASTORE);
  4244.     }
  4245.     else if (type == this_control.float_type)
  4246.     {
  4247.          PutOp(OP_FALOAD);
  4248.          PutOp(OP_FCONST_1);
  4249.          PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_FADD : OP_FSUB);
  4250.          if (need_value)
  4251.              PutOp(OP_DUP_X2);
  4252.          PutOp(OP_FASTORE);
  4253.     }
  4254.     else if (type == this_control.double_type)
  4255.     {
  4256.          PutOp(OP_DALOAD);
  4257.          PutOp(OP_DCONST_1);
  4258.          PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_DADD : OP_DSUB);
  4259.          if (need_value)
  4260.              PutOp(OP_DUP2_X2);
  4261.          PutOp(OP_DASTORE);
  4262.     }
  4263.     else assert(false && "unsupported PreUnary type");
  4264.  
  4265.     return;
  4266. }
  4267.  
  4268.  
  4269. //
  4270. // Pre Unary for which operand is field (instance variable)
  4271. // AstExpression *expression;
  4272. //
  4273. void ByteCode::EmitPreUnaryIncrementExpressionField(int kind, AstPreUnaryExpression *expression, bool need_value)
  4274. {
  4275.     if (kind == LHS_METHOD)
  4276.         ResolveAccess(expression -> expression); // get address and value
  4277.     else // need to load address of object, obtained from resolution, saving a copy on the stack
  4278.         EmitFieldAccessLhs(expression -> expression);
  4279.  
  4280.     TypeSymbol *expression_type = expression -> Type();
  4281.     if (this_control.IsSimpleIntegerValueType(expression_type))
  4282.     {
  4283.         PutOp(OP_ICONST_1);
  4284.         PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_IADD : OP_ISUB);
  4285.         EmitCast(expression_type, this_control.int_type);
  4286.         if (need_value)
  4287.             PutOp(OP_DUP_X1);
  4288.     }
  4289.     else if (expression_type == this_control.long_type)
  4290.     {
  4291.         PutOp(OP_LCONST_1);
  4292.         PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_LADD : OP_LSUB);
  4293.         if (need_value)
  4294.             PutOp(OP_DUP2_X1);
  4295.     }
  4296.     else if (expression_type == this_control.float_type)
  4297.     {
  4298.         PutOp(OP_FCONST_1);
  4299.         PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_FADD : OP_FSUB);
  4300.         if (need_value)
  4301.             PutOp(OP_DUP_X1);
  4302.     }
  4303.     else if (expression_type == this_control.double_type)
  4304.     {
  4305.         PutOp(OP_DCONST_1);
  4306.         PutOp(expression -> pre_unary_tag == AstPreUnaryExpression::PLUSPLUS ? OP_DADD : OP_DSUB);
  4307.         if (need_value)
  4308.             PutOp(OP_DUP2_X1);
  4309.     }
  4310.     else assert(false && "unsupported PreUnary type");
  4311.  
  4312.     if (kind == LHS_METHOD)
  4313.     {
  4314.         int stack_words = (this_control.IsDoubleWordType(expression_type) ? 2 : 1) + 1;
  4315.         PutOp(OP_INVOKESTATIC);
  4316.         CompleteCall(expression -> write_method, stack_words);
  4317.     }
  4318.     else
  4319.     {
  4320.         PutOp(OP_PUTFIELD);
  4321.         ChangeStack(this_control.IsDoubleWordType(expression_type) ? -3 : -2);
  4322.  
  4323.         VariableSymbol *sym = (VariableSymbol *) expression -> symbol;
  4324.         PutU2(RegisterFieldref(VariableTypeResolution(expression -> expression, sym), sym));
  4325.     }
  4326.  
  4327.     return;
  4328. }
  4329.  
  4330.  
  4331. void ByteCode::EmitThisInvocation(AstThisCall *this_call)
  4332. {
  4333.     //
  4334.     // THIS_CALL
  4335.     //    AstExpression *method;
  4336.     //    AstList *arguments;
  4337.     // A call to another constructor (THIS_CALL) or super constructor (SUPER_CALL)
  4338.     // result in the same sort of generated code, as the semantic analysis
  4339.     // has resolved the proper constructor to be invoked.
  4340.     //
  4341.     PutOp(OP_ALOAD_0); // load 'this'
  4342.  
  4343.     int stack_words = 0; // words on stack needed for arguments
  4344.     if (this_call -> base_opt)
  4345.         stack_words += EmitExpression(this_call -> base_opt);
  4346.  
  4347.     for (int i = 0; i < this_call -> NumLocalArguments(); i++)
  4348.         stack_words += EmitExpression((AstExpression *) this_call -> LocalArgument(i));
  4349.  
  4350.     for (int k = 0; k < this_call -> NumArguments(); k++)
  4351.         stack_words += EmitExpression((AstExpression *) this_call -> Argument(k));
  4352.  
  4353.     PutOp(OP_INVOKENONVIRTUAL);
  4354.     ChangeStack(-stack_words);
  4355.  
  4356.     PutU2(RegisterMethodref(unit_type -> fully_qualified_name,
  4357.                             this_call -> symbol -> ExternalIdentity() -> Utf8_literal,
  4358.                             this_call -> symbol -> signature));
  4359.  
  4360.     return;
  4361. }
  4362.  
  4363.  
  4364. void ByteCode::EmitSuperInvocation(AstSuperCall *super_call)
  4365. {
  4366.     PutOp(OP_ALOAD_0); // load 'this'
  4367.  
  4368.     int stack_words = 0; // words on stack needed for arguments
  4369.     if (super_call -> base_opt)
  4370.         stack_words += EmitExpression(super_call -> base_opt);
  4371.  
  4372.     for (int i = 0; i < super_call -> NumLocalArguments(); i++)
  4373.         stack_words += EmitExpression((AstExpression *) super_call -> LocalArgument(i));
  4374.  
  4375.     if (super_call -> NeedsExtraNullArgument())
  4376.     {
  4377.         PutOp(OP_ACONST_NULL);
  4378.         stack_words += 1;
  4379.     }
  4380.  
  4381.     for (int k = 0; k < super_call -> NumArguments(); k++)
  4382.         stack_words += EmitExpression((AstExpression *) super_call -> Argument(k));
  4383.  
  4384.     PutOp(OP_INVOKENONVIRTUAL);
  4385.     ChangeStack(-stack_words);
  4386.  
  4387.     PutU2(RegisterMethodref(unit_type -> super -> fully_qualified_name,
  4388.                             super_call -> symbol -> ExternalIdentity() -> Utf8_literal,
  4389.                             super_call -> symbol -> signature));
  4390.  
  4391.     return;
  4392. }
  4393.  
  4394.  
  4395. //
  4396. //  Methods for string concatenation
  4397. //
  4398. void ByteCode::ConcatenateString(AstBinaryExpression *expression)
  4399. {
  4400.     //
  4401.     // generate code to concatenate strings, by generating a string buffer and appending the arguments
  4402.     // before calling toString, i.e.,
  4403.     //  s1+s2 compiles to
  4404.     //  new StringBuffer().append(s1).append(s2).toString();
  4405.     // look for sequences of concatenation to use a single buffer where possible
  4406.     //
  4407.     // Call appropriate constructor depending on whether or not first operand is a string.
  4408.     //
  4409.     PutOp(OP_NEW);
  4410.     PutU2(RegisterClass(this_control.StringBuffer() -> fully_qualified_name));
  4411.     PutOp(OP_DUP);
  4412.     if (expression -> left_expression -> IsConstant())
  4413.     {
  4414.         assert(expression -> left_expression -> Type() == this_control.String());
  4415.  
  4416.         EmitExpression(expression -> left_expression);
  4417.         PutOp(OP_INVOKENONVIRTUAL);
  4418.         PutU2(RegisterLibraryMethodref(this_control.StringBuffer_InitWithStringMethod()));
  4419.         ChangeStack(-1);
  4420.     }
  4421.     else
  4422.     {
  4423.         PutOp(OP_INVOKENONVIRTUAL);
  4424.         PutU2(RegisterLibraryMethodref(this_control.StringBuffer_InitMethod()));
  4425.  
  4426.         AppendString(expression -> left_expression);
  4427.     }
  4428.  
  4429.     AppendString(expression -> right_expression);
  4430.  
  4431.     //
  4432.     // convert string buffer to string
  4433.     //
  4434.     PutOp(OP_INVOKEVIRTUAL);
  4435.     PutU2(RegisterLibraryMethodref(this_control.StringBuffer_toStringMethod()));
  4436.     ChangeStack(1); // account for return value
  4437.  
  4438.     return;
  4439. }
  4440.  
  4441.  
  4442. void ByteCode::AppendString(AstExpression *expression)
  4443. {
  4444.     TypeSymbol *type = expression -> Type();
  4445.  
  4446.     if (expression -> IsConstant())
  4447.     {
  4448.         assert(type == this_control.String());
  4449.         LoadConstantAtIndex(RegisterString((Utf8LiteralValue *) expression -> value));
  4450.     }
  4451.     else
  4452.     {
  4453.         AstBinaryExpression *binary_expression = expression -> BinaryExpressionCast();
  4454.         if (binary_expression)
  4455.         {
  4456.             if (binary_expression -> binary_tag == AstBinaryExpression::PLUS &&
  4457.                 (IsReferenceType(binary_expression -> left_expression -> Type()) ||
  4458.                  IsReferenceType(binary_expression -> right_expression -> Type())))
  4459.             {
  4460.                 AppendString(binary_expression -> left_expression);
  4461.                 AppendString(binary_expression -> right_expression);
  4462.  
  4463.                 return;
  4464.             }
  4465.         }
  4466.  
  4467.         if (expression -> ParenthesizedExpressionCast())
  4468.         {
  4469.             AppendString(expression -> ParenthesizedExpressionCast() -> expression);
  4470.             return;
  4471.         }
  4472.  
  4473.         AstCastExpression *cast = expression -> CastExpressionCast();
  4474.         if (cast) // here if cast expression, verify that converting to string
  4475.         {
  4476.             if (cast -> kind == Ast::CAST && cast -> Type() == this_control.String())
  4477.             {
  4478.                 AppendString(cast -> expression);
  4479.                 return;
  4480.             }
  4481.         }
  4482.  
  4483.         EmitExpression(expression);
  4484.     }
  4485.  
  4486.     EmitStringAppendMethod(type);
  4487.  
  4488.     return;
  4489. }
  4490.  
  4491.  
  4492. void ByteCode::EmitStringAppendMethod(TypeSymbol *type)
  4493. {
  4494.     //
  4495.     // Find appropriate append routine to add to string buffer
  4496.     //
  4497.     MethodSymbol *append_method =
  4498.             (type -> num_dimensions == 1 && type -> base_type == this_control.char_type
  4499.                    ? this_control.StringBuffer_append_char_arrayMethod()
  4500.                    : type == this_control.char_type
  4501.                           ? this_control.StringBuffer_append_charMethod()
  4502.                           : type == this_control.boolean_type
  4503.                                  ? this_control.StringBuffer_append_booleanMethod()
  4504.                                  : type == this_control.int_type ||
  4505.                                    type == this_control.short_type ||
  4506.                                    type == this_control.byte_type
  4507.                                         ? this_control.StringBuffer_append_intMethod()
  4508.                                         : type == this_control.long_type
  4509.                                                ? this_control.StringBuffer_append_longMethod()
  4510.                                                : type == this_control.float_type
  4511.                                                       ? this_control.StringBuffer_append_floatMethod()
  4512.                                                       : type == this_control.double_type
  4513.                                                              ? this_control.StringBuffer_append_doubleMethod()
  4514.                                                              : type == this_control.String()
  4515.                                                                     ? this_control.StringBuffer_append_stringMethod()
  4516.                                                                     : IsReferenceType(type)
  4517.                                                                           ? this_control.StringBuffer_append_objectMethod()
  4518.                                                                           : this_control.StringBuffer_InitMethod()); // for assertion
  4519.  
  4520.     assert(append_method != this_control.StringBuffer_InitMethod() && "unable to find method for string buffer concatenation");
  4521.  
  4522.     PutOp(OP_INVOKEVIRTUAL);
  4523.     ChangeStack(this_control.IsDoubleWordType(type) ? -2 : -1);
  4524.     PutU2(RegisterLibraryMethodref(append_method));
  4525.     ChangeStack(1); // account for return value
  4526.  
  4527.     return;
  4528. }
  4529.  
  4530.  
  4531. #ifdef TEST
  4532. static void op_trap()
  4533. {
  4534.     int i = 0; // used for debugger trap
  4535.     i++;       // avoid compiler warnings about unused variable
  4536. }
  4537. #endif
  4538.  
  4539.  
  4540. ByteCode::ByteCode(TypeSymbol *unit_type) : ClassFile(unit_type),
  4541.                                             this_control(unit_type -> semantic_environment -> sem -> control),
  4542.                                             this_semantic(*unit_type -> semantic_environment -> sem),
  4543.  
  4544.                                             string_overflow(false),
  4545.                                             library_method_not_found(false),
  4546.  
  4547.                                             double_constant_pool_index(NULL),
  4548.                                             integer_constant_pool_index(NULL),
  4549.                                             long_constant_pool_index(NULL),
  4550.                                             float_constant_pool_index(NULL),
  4551.                                             string_constant_pool_index(NULL),
  4552.  
  4553.                                             utf8_constant_pool_index(segment_pool, this_control.Utf8_pool.symbol_pool.Length()),
  4554.                                             class_constant_pool_index(segment_pool, this_control.Utf8_pool.symbol_pool.Length()),
  4555.  
  4556.                                             name_and_type_constant_pool_index(NULL),
  4557.                                             fieldref_constant_pool_index(NULL),
  4558.                                             methodref_constant_pool_index(NULL)
  4559. {
  4560. #ifdef TEST
  4561.     if (! this_control.option.nowrite)
  4562.         this_control.class_files_written++;
  4563. #endif
  4564.  
  4565.     SetFlags(unit_type -> Flags());
  4566.  
  4567.     //
  4568.     // The flags for 'static' and 'protected' are set only for the inner
  4569.     // classes attribute, not for the class, as described in page 25
  4570.     // of the inner classes document.
  4571.     //
  4572.     if (unit_type -> ACC_PROTECTED())
  4573.     {
  4574.         this -> ResetACC_PROTECTED();
  4575.         this -> SetACC_PUBLIC();
  4576.     }
  4577.     this -> ResetACC_STATIC();
  4578.     this -> ResetACC_PRIVATE();
  4579.     this -> SetACC_SUPER(); // must always set ACC_SUPER for class (cf page 96 of revised JVM Spec)
  4580.  
  4581.     magic = 0xcafebabe;
  4582.     major_version = 45;             // use Sun JDK 1.0 version numbers
  4583.     minor_version = 3;
  4584.     constant_pool.Next() = NULL;
  4585.     this_class = RegisterClass(unit_type -> fully_qualified_name);
  4586.  
  4587.     super_class = (unit_type -> super ? RegisterClass(unit_type -> super -> fully_qualified_name) : 0);
  4588.  
  4589.     for (int k = 0; k < unit_type -> NumInterfaces(); k++)
  4590.         interfaces.Next() = RegisterClass(unit_type -> Interface(k) -> fully_qualified_name);
  4591.  
  4592.     return;
  4593. }
  4594.  
  4595.  
  4596. //
  4597. //  Methods for manipulating labels
  4598. //
  4599. void ByteCode::DefineLabel(Label& lab)
  4600. {
  4601.     assert((! lab.defined) && "duplicate label definition");
  4602.  
  4603.     lab.defined = true;
  4604.     lab.definition = code_attribute -> CodeLength();
  4605.     if (lab.definition > last_label_pc)
  4606.         last_label_pc = lab.definition;
  4607.  
  4608.     return;
  4609. }
  4610.  
  4611.  
  4612. //
  4613. // patch all uses to have proper value. This requires that
  4614. // all labels be freed at some time.
  4615. //
  4616. void ByteCode::CompleteLabel(Label& lab)
  4617. {
  4618.     if (lab.uses.Length() > 0)
  4619.     {
  4620.         assert((lab.defined) && "label used but with no definition");
  4621.  
  4622.         //
  4623.         // patch byte code reference to label to reflect it's definition
  4624.         // as 16-bit signed offset.
  4625.         //
  4626.         for (int i = 0; i < lab.uses.Length(); i++)
  4627.         {
  4628.             unsigned int luse = lab.uses[i].use_offset;
  4629.             int start = luse - lab.uses[i].op_offset,
  4630.                 offset = lab.definition - start;
  4631.             if (lab.uses[i].use_length == 2) // here if short offset
  4632.             {
  4633.                 code_attribute -> ResetCode(luse, (offset >> 8) & 0xFF);
  4634.                 code_attribute -> ResetCode(luse + 1, offset & 0xFF);
  4635.             }
  4636.             else if (lab.uses[i].use_length == 4) // here if 4 byte use
  4637.             {
  4638.                 code_attribute -> ResetCode(luse, (offset >> 24) & 0xFF);
  4639.                 code_attribute -> ResetCode(luse + 1, (offset >> 16) & 0xFF);
  4640.                 code_attribute -> ResetCode(luse + 2, (offset >>  8) & 0xFF);
  4641.                 code_attribute -> ResetCode(luse + 3, offset & 0xFF);
  4642.             }
  4643.             else assert(false &&  "label use length not 2 or 4");
  4644.         }
  4645.     }
  4646.  
  4647.     //
  4648.     // reset in case label is used again.
  4649.     //
  4650.     lab.Reset();
  4651.  
  4652.     return;
  4653. }
  4654.  
  4655.  
  4656. void ByteCode::UseLabel(Label &lab, int _length, int _op_offset)
  4657. {
  4658.     int lab_index = lab.uses.NextIndex();
  4659.     lab.uses[lab_index].use_length = _length;
  4660.     lab.uses[lab_index].op_offset = _op_offset;
  4661.     lab.uses[lab_index].use_offset = code_attribute -> CodeLength();
  4662.  
  4663.     //
  4664.     // fill next length bytes with zero; will be filled in with proper value when label completed
  4665.     //
  4666.     for (int i = 0; i < lab.uses[lab_index].use_length; i++)
  4667.         code_attribute -> AddCode(0);
  4668.  
  4669.     return;
  4670. }
  4671.  
  4672.  
  4673. void ByteCode::LoadLocal(int varno, TypeSymbol *type)
  4674. {
  4675.     if (this_control.IsSimpleIntegerValueType(type) || type == this_control.boolean_type)
  4676.     {
  4677.          if (varno <= 3)
  4678.               PutOp(OP_ILOAD_0 + varno);
  4679.          else PutOpWide(OP_ILOAD, varno);
  4680.     }
  4681.     else if (type == this_control.long_type)
  4682.     {
  4683.          if (varno <= 3)
  4684.               PutOp(OP_LLOAD_0 + varno);
  4685.          else PutOpWide(OP_LLOAD, varno);
  4686.     }
  4687.     else if (type == this_control.float_type)
  4688.     {
  4689.          if (varno <= 3)
  4690.               PutOp(OP_FLOAD_0 + varno);
  4691.          else PutOpWide(OP_FLOAD, varno);
  4692.     }
  4693.     else if (type == this_control.double_type)
  4694.     {
  4695.          if (varno <= 3)
  4696.               PutOp(OP_DLOAD_0 + varno);
  4697.          else PutOpWide(OP_DLOAD, varno);
  4698.     }
  4699.     else // assume reference
  4700.     {
  4701.          if (varno <= 3)
  4702.               PutOp(OP_ALOAD_0 + varno);
  4703.          else PutOpWide(OP_ALOAD, varno);
  4704.     }
  4705.  
  4706.     return;
  4707. }
  4708.  
  4709.  
  4710. //
  4711. // see if can load without using LDC even if have literal index; otherwise generate constant pool entry
  4712. // if one has not yet been generated.
  4713. //
  4714. //
  4715. void ByteCode::LoadLiteral(LiteralValue *litp, TypeSymbol *type)
  4716. {
  4717.     if (litp == this_control.NullValue())
  4718.     {
  4719.         PutOp(OP_ACONST_NULL);
  4720.     }
  4721.     else if (this_control.IsSimpleIntegerValueType(type) || type == this_control.boolean_type) // load literal using literal value
  4722.     {
  4723.         IntLiteralValue *vp = (IntLiteralValue *) litp;
  4724.         int val = vp -> value;
  4725.         if (val >= -32768 && val < 32768) // In this case, we might be able to use an immediate instruction
  4726.              LoadImmediateInteger(val);
  4727.         else LoadConstantAtIndex(RegisterInteger(vp));
  4728.     }
  4729.     else if (type == this_control.String()) // register index as string if this has not yet been done
  4730.     {
  4731.         LoadConstantAtIndex(RegisterString((Utf8LiteralValue *) litp));
  4732.     }
  4733.     else if (type == this_control.long_type)
  4734.     {
  4735.         LongLiteralValue *vp = (LongLiteralValue *) litp;
  4736.         if (vp -> value == 0)
  4737.              PutOp(OP_LCONST_0);
  4738.         else if (vp -> value == 1)
  4739.              PutOp(OP_LCONST_1);
  4740.         else
  4741.         {
  4742.              PutOp(OP_LDC2_W);
  4743.              PutU2(RegisterLong(vp));
  4744.         }
  4745.     }
  4746.     else if (type == this_control.float_type)
  4747.     {
  4748.         FloatLiteralValue *vp = (FloatLiteralValue *) litp;
  4749.         IEEEfloat val = vp -> value;
  4750.         if (val.Word() == 0) // if float 0.0
  4751.              PutOp(OP_FCONST_0);
  4752.         else if (val.Word() == 0x3f800000) // if float 1.0
  4753.              PutOp(OP_FCONST_1);
  4754.         else if (val.Word() == 0x40000000) // if float 2.0
  4755.              PutOp(OP_FCONST_2);
  4756.         else LoadConstantAtIndex(RegisterFloat(vp));
  4757.     }
  4758.     else if (type == this_control.double_type)
  4759.     {
  4760.         DoubleLiteralValue *vp = (DoubleLiteralValue *) litp;
  4761.         IEEEdouble val = vp -> value;
  4762.         if (val.HighWord() == 0 && val.LowWord() == 0)
  4763.              PutOp(OP_DCONST_0);
  4764.         else if (val.HighWord() == 0x3ff00000 && val.LowWord() == 0x00000000) // if double 1.0
  4765.              PutOp(OP_DCONST_1);
  4766.         else
  4767.         {
  4768.              PutOp(OP_LDC2_W);
  4769.              PutU2(RegisterDouble(vp));
  4770.         }
  4771.     }
  4772.     else assert(false && "unsupported constant kind");
  4773.  
  4774.     return;
  4775. }
  4776.  
  4777.  
  4778. void ByteCode::LoadImmediateInteger(int val)
  4779. {
  4780.     if (val >= -1 && val <= 5)
  4781.          PutOp(OP_ICONST_0 + val); // exploit opcode encoding
  4782.     else if (val >= -128 && val < 128)
  4783.     {
  4784.          PutOp(OP_BIPUSH);
  4785.          PutU1(val);
  4786.     }
  4787.     else
  4788.     {
  4789.         //
  4790.         // For a short value, look to see if it is already in the constant pool.
  4791.         // For a value outside the short range, make sure it is entered in the
  4792.         // constant pool.
  4793.         //
  4794.         u2 index = (val >= -32768 && val < 32768 ? FindInteger(this_control.int_pool.Find(val))
  4795.                                                  : RegisterInteger(this_control.int_pool.FindOrInsert(val)));
  4796.         if (index == 0) // a short value that was not previously registered in the constant pool
  4797.         {
  4798.             PutOp(OP_SIPUSH);
  4799.             PutU1(val >> 8);
  4800.             PutU1(val);
  4801.         }
  4802.         else LoadConstantAtIndex(index);
  4803.     }
  4804.  
  4805.     return;
  4806. }
  4807.  
  4808.  
  4809. //
  4810. // Call to an access method for a compound operator such as ++, --,
  4811. // or "op=".
  4812. //
  4813. void ByteCode::ResolveAccess(AstExpression *p)
  4814. {
  4815.     AstFieldAccess *field = p -> FieldAccessCast();
  4816.     AstExpression *resolve_expression = (field ? field -> resolution_opt : p -> SimpleNameCast() -> resolution_opt);
  4817.     AstMethodInvocation *read_method = resolve_expression -> MethodInvocationCast();
  4818.  
  4819.     assert(read_method && read_method -> NumArguments() == 1); // a read method has exactly one argument: the object in question.
  4820.  
  4821.     int stack_words = EmitExpression((AstExpression *) read_method -> Argument(0));
  4822.     PutOp(OP_DUP);
  4823.     PutOp(OP_INVOKESTATIC);
  4824.     CompleteCall(read_method -> symbol -> MethodCast(), stack_words);
  4825.  
  4826.     return;
  4827. }
  4828.  
  4829.  
  4830. int ByteCode::LoadVariable(int kind, AstExpression *expr)
  4831. {
  4832.     VariableSymbol *sym = (VariableSymbol *) expr -> symbol;
  4833.     TypeSymbol *expression_type = expr -> Type();
  4834.     switch (kind)
  4835.     {
  4836.         case LHS_LOCAL:
  4837.              LoadLocal(sym -> LocalVariableIndex(), expression_type);
  4838.              break;
  4839.         case LHS_METHOD:
  4840.              EmitExpression(expr); // will do resolution
  4841.              break;
  4842.         case LHS_FIELD:
  4843.         case LHS_STATIC:
  4844.              {
  4845.                  if (sym -> ACC_STATIC())
  4846.                  {
  4847.                      PutOp(OP_GETSTATIC);
  4848.                      ChangeStack(GetTypeWords(expression_type));
  4849.                  }
  4850.                  else
  4851.                  {
  4852.                      PutOp(OP_ALOAD_0); // get address of "this"
  4853.                      PutOp(OP_GETFIELD);
  4854.                      ChangeStack(GetTypeWords(expression_type) - 1);
  4855.                  }
  4856.  
  4857.                  PutU2(RegisterFieldref(VariableTypeResolution(expr, sym), sym));
  4858.              }
  4859.              break;
  4860.         default:
  4861.              assert(false && "LoadVariable bad kind");
  4862.     }
  4863.  
  4864.     return GetTypeWords(expression_type);
  4865. }
  4866.  
  4867.  
  4868. //
  4869. // load reference from local variable.
  4870. // otherwise will use getstatic or getfield.
  4871. //
  4872. void ByteCode::LoadReference(AstExpression *expression)
  4873. {
  4874.     if (expression -> ParenthesizedExpressionCast())
  4875.         expression = UnParenthesize(expression);
  4876.  
  4877.     VariableSymbol *sym = expression -> symbol -> VariableCast();
  4878.     if (sym && sym -> owner -> MethodCast()) // a local variable ?
  4879.     {
  4880.         int varno = sym -> LocalVariableIndex();
  4881.         LoadLocal(varno, expression -> Type());
  4882.         return;
  4883.     }
  4884.  
  4885.     AstFieldAccess *field_access = expression -> FieldAccessCast();
  4886.     if (field_access)
  4887.     {
  4888.         if (field_access -> resolution_opt) // This field access was resolved... Process the resolution
  4889.         {
  4890.             EmitExpression(field_access -> resolution_opt);
  4891.             return;
  4892.         }
  4893.  
  4894.         if (sym -> ACC_STATIC())
  4895.         {
  4896.             PutOp(OP_GETSTATIC);
  4897.             ChangeStack(1);
  4898.         }
  4899.         else
  4900.         {
  4901.             EmitExpression(field_access -> base);
  4902.             PutOp(OP_GETFIELD);
  4903.             ChangeStack(0);
  4904.         }
  4905.  
  4906.         PutU2(RegisterFieldref(VariableTypeResolution(field_access, sym), sym));
  4907.     }
  4908.     else if (expression -> ArrayAccessCast()) // nested array reference
  4909.     {
  4910.         EmitArrayAccessLhs(expression -> ArrayAccessCast());
  4911.         PutOp(OP_AALOAD);
  4912.     }
  4913.     else // must have expression, the value of which is reference
  4914.         EmitExpression(expression);
  4915.  
  4916.     return;
  4917. }
  4918.  
  4919.  
  4920. int ByteCode::LoadArrayElement(TypeSymbol *type)
  4921. {
  4922.     PutOp(type == this_control.byte_type || type == this_control.boolean_type
  4923.                 ? OP_BALOAD
  4924.                 : type == this_control.short_type
  4925.                         ? OP_SALOAD
  4926.                         : type == this_control.int_type
  4927.                                 ? OP_IALOAD
  4928.                                 : type == this_control.long_type
  4929.                                         ? OP_LALOAD
  4930.                                         : type == this_control.char_type
  4931.                                                 ? OP_CALOAD
  4932.                                                 : type == this_control.float_type
  4933.                                                         ? OP_FALOAD
  4934.                                                         : type == this_control.double_type
  4935.                                                                 ? OP_DALOAD
  4936.                                                                 : OP_AALOAD); // assume reference
  4937.  
  4938.     return GetTypeWords(type);
  4939. }
  4940.  
  4941.  
  4942. void ByteCode::StoreArrayElement(TypeSymbol *type)
  4943. {
  4944.     PutOp(type == this_control.byte_type || type == this_control.boolean_type
  4945.                 ? OP_BASTORE
  4946.                 : type == this_control.short_type
  4947.                         ? OP_SASTORE
  4948.                         : type == this_control.int_type
  4949.                                 ? OP_IASTORE
  4950.                                 : type == this_control.long_type
  4951.                                         ? OP_LASTORE
  4952.                                         : type == this_control.char_type
  4953.                                                 ? OP_CASTORE
  4954.                                                 : type == this_control.float_type
  4955.                                                         ? OP_FASTORE
  4956.                                                         : type == this_control.double_type
  4957.                                                                 ? OP_DASTORE
  4958.                                                                 : OP_AASTORE); // assume reference
  4959.  
  4960.     return;
  4961. }
  4962.  
  4963.  
  4964. //
  4965. //  Method to generate field reference
  4966. //
  4967. void ByteCode::StoreField(AstExpression *expression)
  4968. {
  4969.     VariableSymbol *sym = (VariableSymbol *) expression -> symbol;
  4970.     TypeSymbol *expression_type = expression -> Type();
  4971.     if (sym -> ACC_STATIC())
  4972.     {
  4973.         PutOp(OP_PUTSTATIC);
  4974.         ChangeStack(this_control.IsDoubleWordType(expression_type) ? -2 : -1);
  4975.     }
  4976.     else
  4977.     {
  4978.         PutOp(OP_PUTFIELD);
  4979.         ChangeStack(this_control.IsDoubleWordType(expression_type) ? -3 : -2);
  4980.     }
  4981.  
  4982.     PutU2(RegisterFieldref(VariableTypeResolution(expression, sym), sym));
  4983.  
  4984.     return;
  4985. }
  4986.  
  4987.  
  4988. void ByteCode::StoreLocal(int varno, TypeSymbol *type)
  4989. {
  4990.     if (this_control.IsSimpleIntegerValueType(type) || type == this_control.boolean_type)
  4991.     {
  4992.          if (varno <= 3)
  4993.               PutOp(OP_ISTORE_0 + varno);
  4994.          else PutOpWide(OP_ISTORE, varno);
  4995.     }
  4996.     else if (type == this_control.long_type)
  4997.     {
  4998.          if (varno <= 3)
  4999.               PutOp(OP_LSTORE_0 + varno);
  5000.          else PutOpWide(OP_LSTORE, varno);
  5001.     }
  5002.     else if (type == this_control.float_type)
  5003.     {
  5004.          if (varno <= 3)
  5005.               PutOp(OP_FSTORE_0 + varno);
  5006.          else PutOpWide(OP_FSTORE, varno);
  5007.     }
  5008.     else if (type == this_control.double_type)
  5009.     {
  5010.          if (varno <= 3)
  5011.               PutOp(OP_DSTORE_0 + varno);
  5012.          else PutOpWide(OP_DSTORE, varno);
  5013.     }
  5014.     else // assume reference
  5015.     {
  5016.          if (varno <= 3)
  5017.               PutOp(OP_ASTORE_0 + varno);
  5018.          else PutOpWide(OP_ASTORE, varno);
  5019.     }
  5020.  
  5021.     return;
  5022. }
  5023.  
  5024.  
  5025. void ByteCode::StoreVariable(int kind, AstExpression *expr)
  5026. {
  5027.     VariableSymbol *sym = (VariableSymbol *) expr -> symbol;
  5028.     switch (kind)
  5029.     {
  5030.         case LHS_LOCAL:
  5031.              StoreLocal(sym -> LocalVariableIndex(), sym -> Type());
  5032.              break;
  5033.         case LHS_FIELD:
  5034.         case LHS_STATIC:
  5035.              {
  5036.                  if (sym -> ACC_STATIC())
  5037.                  {
  5038.                      PutOp(OP_PUTSTATIC);
  5039.                      ChangeStack(this_control.IsDoubleWordType(expr -> Type()) ? -2 : -1);
  5040.                  }
  5041.                  else
  5042.                  {
  5043.                      PutOp(OP_ALOAD_0); // get address of "this"
  5044.                      PutOp(OP_PUTFIELD);
  5045.                      ChangeStack(this_control.IsDoubleWordType(expr -> Type()) ? -3 : -2);
  5046.                  }
  5047.  
  5048.                  PutU2(RegisterFieldref(VariableTypeResolution(expr, sym), sym));
  5049.              }
  5050.              break;
  5051.         default:
  5052.             assert(false && "StoreVariable bad kind");
  5053.     }
  5054.  
  5055.     return;
  5056. }
  5057.  
  5058.  
  5059. //
  5060. // finish off code by writing SourceFile attribute
  5061. // and InnerClasses attribute (if appropriate)
  5062. //
  5063. void ByteCode::FinishCode(TypeSymbol *type)
  5064. {
  5065.     attributes.Next() = new SourceFile_attribute(RegisterUtf8(this_control.Sourcefile_literal),
  5066.                                                  RegisterUtf8(type -> file_symbol -> FileNameLiteral()));
  5067.  
  5068.     if (type == NULL)
  5069.         return; // return if interface type
  5070.  
  5071.     if (type -> IsLocal() || type -> IsNested() || type -> NumNestedTypes() > 0) // here to generate InnerClasses attribute
  5072.     {
  5073.         inner_classes_attribute = new InnerClasses_attribute(RegisterUtf8(this_control.InnerClasses_literal));
  5074.  
  5075.         //
  5076.         // need to build chain from this type to its owner all the way to the containing type
  5077.         // and then write that out in reverse order (so containing type comes first),
  5078.         // and then write out an entry for each immediately contained type
  5079.         //
  5080.         Tuple<TypeSymbol *> owners;
  5081.         for (TypeSymbol *t = type; t && t != type -> outermost_type; t = t -> ContainingType())
  5082.             owners.Next() = t;
  5083.  
  5084.         for (int j = owners.Length() - 1; j >= 0; j--)
  5085.         {
  5086.             TypeSymbol *outer = owners[j];
  5087.             inner_classes_attribute -> AddInnerClass(RegisterClass(outer -> fully_qualified_name),
  5088.                                                      outer -> IsLocal()
  5089.                                                             ? 0
  5090.                                                             : RegisterClass(outer -> ContainingType() -> fully_qualified_name),
  5091.                                                      outer -> Anonymous()
  5092.                                                             ? 0
  5093.                                                             : RegisterUtf8(outer -> name_symbol -> Utf8_literal),
  5094.                                                      outer -> Flags());
  5095.         }
  5096.  
  5097.         for (int k = 0; k < type -> NumNestedTypes(); k++)
  5098.         {
  5099.             TypeSymbol *nested = type -> NestedType(k);
  5100.             inner_classes_attribute -> AddInnerClass(RegisterClass(nested -> fully_qualified_name),
  5101.                                                      nested -> IsLocal()
  5102.                                                              ? 0
  5103.                                                              : RegisterClass(nested -> ContainingType() -> fully_qualified_name),
  5104.                                                      nested -> Anonymous()
  5105.                                                              ? 0
  5106.                                                              : RegisterUtf8(nested -> name_symbol -> Utf8_literal),
  5107.                                                      nested -> Flags());
  5108.         }
  5109.  
  5110.         attributes.Next() = inner_classes_attribute;
  5111.     }
  5112.  
  5113.     if (type -> IsDeprecated())
  5114.         attributes.Next() = CreateDeprecatedAttribute();
  5115.  
  5116.     return;
  5117. }
  5118.  
  5119.  
  5120. void ByteCode::PutOp(unsigned char opc)
  5121. {
  5122. #ifdef TEST
  5123.     if (this_control.option.debug_trap_op > 0 && code_attribute -> CodeLength() == this_control.option.debug_trap_op)
  5124.         op_trap();
  5125.  
  5126.     //
  5127.     // debug trick - force branch on opcode to see what opcode we are compiling
  5128.     //
  5129.     switch (opc)
  5130.     {
  5131.         case OP_NOP: break;
  5132.         case OP_ACONST_NULL: break;
  5133.         case OP_ICONST_M1: break;
  5134.         case OP_ICONST_0: break;
  5135.         case OP_ICONST_1: break;
  5136.         case OP_ICONST_2: break;
  5137.         case OP_ICONST_3: break;
  5138.         case OP_ICONST_4: break;
  5139.         case OP_ICONST_5: break;
  5140.         case OP_LCONST_0: break;
  5141.         case OP_LCONST_1: break;
  5142.         case OP_FCONST_0: break;
  5143.         case OP_FCONST_1: break;
  5144.         case OP_FCONST_2: break;
  5145.         case OP_DCONST_0: break;
  5146.         case OP_DCONST_1: break;
  5147.         case OP_BIPUSH: break;
  5148.         case OP_SIPUSH: break;
  5149.         case OP_LDC: break;
  5150.         case OP_LDC_W: break;
  5151.         case OP_LDC2_W: break;
  5152.         case OP_ILOAD: break;
  5153.         case OP_LLOAD: break;
  5154.         case OP_FLOAD: break;
  5155.         case OP_DLOAD: break;
  5156.         case OP_ALOAD: break;
  5157.         case OP_ILOAD_0: break;
  5158.         case OP_ILOAD_1: break;
  5159.         case OP_ILOAD_2: break;
  5160.         case OP_ILOAD_3: break;
  5161.         case OP_LLOAD_0: break;
  5162.         case OP_LLOAD_1: break;
  5163.         case OP_LLOAD_2: break;
  5164.         case OP_LLOAD_3: break;
  5165.         case OP_FLOAD_0: break;
  5166.         case OP_FLOAD_1: break;
  5167.         case OP_FLOAD_2: break;
  5168.         case OP_FLOAD_3: break;
  5169.         case OP_DLOAD_0: break;
  5170.         case OP_DLOAD_1: break;
  5171.         case OP_DLOAD_2: break;
  5172.         case OP_DLOAD_3: break;
  5173.         case OP_ALOAD_0: break;
  5174.         case OP_ALOAD_1: break;
  5175.         case OP_ALOAD_2: break;
  5176.         case OP_ALOAD_3: break;
  5177.         case OP_IALOAD: break;
  5178.         case OP_LALOAD: break;
  5179.         case OP_FALOAD: break;
  5180.         case OP_DALOAD: break;
  5181.         case OP_AALOAD: break;
  5182.         case OP_BALOAD: break;
  5183.         case OP_CALOAD: break;
  5184.         case OP_SALOAD: break;
  5185.         case OP_ISTORE: break;
  5186.         case OP_LSTORE: break;
  5187.         case OP_FSTORE: break;
  5188.         case OP_DSTORE: break;
  5189.         case OP_ASTORE: break;
  5190.         case OP_ISTORE_0: break;
  5191.         case OP_ISTORE_1: break;
  5192.         case OP_ISTORE_2: break;
  5193.         case OP_ISTORE_3: break;
  5194.         case OP_LSTORE_0: break;
  5195.         case OP_LSTORE_1: break;
  5196.         case OP_LSTORE_2: break;
  5197.         case OP_LSTORE_3: break;
  5198.         case OP_FSTORE_0: break;
  5199.         case OP_FSTORE_1: break;
  5200.         case OP_FSTORE_2: break;
  5201.         case OP_FSTORE_3: break;
  5202.         case OP_DSTORE_0: break;
  5203.         case OP_DSTORE_1: break;
  5204.         case OP_DSTORE_2: break;
  5205.         case OP_DSTORE_3: break;
  5206.         case OP_ASTORE_0: break;
  5207.         case OP_ASTORE_1: break;
  5208.         case OP_ASTORE_2: break;
  5209.         case OP_ASTORE_3: break;
  5210.         case OP_IASTORE: break;
  5211.         case OP_LASTORE: break;
  5212.         case OP_FASTORE: break;
  5213.         case OP_DASTORE: break;
  5214.         case OP_AASTORE: break;
  5215.         case OP_BASTORE: break;
  5216.         case OP_CASTORE: break;
  5217.         case OP_SASTORE: break;
  5218.         case OP_POP: break;
  5219.         case OP_POP2: break;
  5220.         case OP_DUP: break;
  5221.         case OP_DUP_X1: break;
  5222.         case OP_DUP_X2: break;
  5223.         case OP_DUP2: break;
  5224.         case OP_DUP2_X1: break;
  5225.         case OP_DUP2_X2: break;
  5226.         case OP_SWAP: break;
  5227.         case OP_IADD: break;
  5228.         case OP_LADD: break;
  5229.         case OP_FADD: break;
  5230.         case OP_DADD: break;
  5231.         case OP_ISUB: break;
  5232.         case OP_LSUB: break;
  5233.         case OP_FSUB: break;
  5234.         case OP_DSUB: break;
  5235.         case OP_IMUL: break;
  5236.         case OP_LMUL: break;
  5237.         case OP_FMUL: break;
  5238.         case OP_DMUL: break;
  5239.         case OP_IDIV: break;
  5240.         case OP_LDIV: break;
  5241.         case OP_FDIV: break;
  5242.         case OP_DDIV: break;
  5243.         case OP_IREM: break;
  5244.         case OP_LREM: break;
  5245.         case OP_FREM: break;
  5246.         case OP_DREM: break;
  5247.         case OP_INEG: break;
  5248.         case OP_LNEG: break;
  5249.         case OP_FNEG: break;
  5250.         case OP_DNEG: break;
  5251.         case OP_ISHL: break;
  5252.         case OP_LSHL: break;
  5253.         case OP_ISHR: break;
  5254.         case OP_LSHR: break;
  5255.         case OP_IUSHR: break;
  5256.         case OP_LUSHR: break;
  5257.         case OP_IAND: break;
  5258.         case OP_LAND: break;
  5259.         case OP_IOR: break;
  5260.         case OP_LOR: break;
  5261.         case OP_IXOR: break;
  5262.         case OP_LXOR: break;
  5263.         case OP_IINC: break;
  5264.         case OP_I2L: break;
  5265.         case OP_I2F: break;
  5266.         case OP_I2D: break;
  5267.         case OP_L2I: break;
  5268.         case OP_L2F: break;
  5269.         case OP_L2D: break;
  5270.         case OP_F2I: break;
  5271.         case OP_F2L: break;
  5272.         case OP_F2D: break;
  5273.         case OP_D2I: break;
  5274.         case OP_D2L: break;
  5275.         case OP_D2F: break;
  5276.         case OP_I2B: break;
  5277.         case OP_I2C: break;
  5278.         case OP_I2S: break;
  5279.         case OP_LCMP: break;
  5280.         case OP_FCMPL: break;
  5281.         case OP_FCMPG: break;
  5282.         case OP_DCMPL: break;
  5283.         case OP_DCMPG: break;
  5284.         case OP_IFEQ: break;
  5285.         case OP_IFNE: break;
  5286.         case OP_IFLT: break;
  5287.         case OP_IFGE: break;
  5288.         case OP_IFGT: break;
  5289.         case OP_IFLE: break;
  5290.         case OP_IF_ICMPEQ: break;
  5291.         case OP_IF_ICMPNE: break;
  5292.         case OP_IF_ICMPLT: break;
  5293.         case OP_IF_ICMPGE: break;
  5294.         case OP_IF_ICMPGT: break;
  5295.         case OP_IF_ICMPLE: break;
  5296.         case OP_IF_ACMPEQ: break;
  5297.         case OP_IF_ACMPNE: break;
  5298.         case OP_GOTO: break;
  5299.         case OP_JSR: break;
  5300.         case OP_RET: break;
  5301.         case OP_TABLESWITCH: break;
  5302.         case OP_LOOKUPSWITCH: break;
  5303.         case OP_IRETURN: break;
  5304.         case OP_LRETURN: break;
  5305.         case OP_FRETURN: break;
  5306.         case OP_DRETURN: break;
  5307.         case OP_ARETURN: break;
  5308.         case OP_RETURN: break;
  5309.         case OP_GETSTATIC: break;
  5310.         case OP_PUTSTATIC: break;
  5311.         case OP_GETFIELD: break;
  5312.         case OP_PUTFIELD: break;
  5313.         case OP_INVOKEVIRTUAL: break;
  5314.         case OP_INVOKENONVIRTUAL: break;
  5315.         case OP_INVOKESTATIC: break;
  5316.         case OP_INVOKEINTERFACE: break;
  5317.         case OP_XXXUNUSEDXXX: break;
  5318.         case OP_NEW: break;
  5319.         case OP_NEWARRAY: break;
  5320.         case OP_ANEWARRAY: break;
  5321.         case OP_ARRAYLENGTH: break;
  5322.         case OP_ATHROW: break;
  5323.         case OP_CHECKCAST: break;
  5324.         case OP_INSTANCEOF: break;
  5325.         case OP_MONITORENTER: break;
  5326.         case OP_MONITOREXIT: break;
  5327.         case OP_WIDE: break;
  5328.         case OP_MULTIANEWARRAY: break;
  5329.         case OP_IFNULL: break;
  5330.         case OP_IFNONNULL: break;
  5331.         case OP_GOTO_W: break;
  5332.         case OP_JSR_W: break;
  5333.         case OP_SOFTWARE: break;
  5334.         case OP_HARDWARE: break;
  5335.     }
  5336. #endif
  5337.  
  5338.     last_op_pc = code_attribute -> CodeLength(); // save pc at start of operation
  5339.     code_attribute -> AddCode(opc);
  5340.     ChangeStack(stack_effect[opc]);
  5341.  
  5342.     return;
  5343. }
  5344.  
  5345. void ByteCode::PutOpWide(unsigned char opc, u2 var)
  5346. {
  5347.     if (var <= 255)  // if can use standard form
  5348.     {
  5349.         PutOp(opc);
  5350.         PutU1(var);
  5351.     }
  5352.     else // need wide form
  5353.     {
  5354.         PutOp(OP_WIDE);
  5355.         PutOp(opc);
  5356.         PutU2(var);
  5357.     }
  5358.  
  5359.     return;
  5360. }
  5361.  
  5362. void ByteCode::PutOpIINC(u2 var, int val)
  5363. {
  5364.     if (var <= 255 && (val >= -128 && val <= 127))  // if can use standard form
  5365.     {
  5366.         PutOp(OP_IINC);
  5367.         PutU1(var);
  5368.         PutU1(val);
  5369.     }
  5370.     else // else need wide form
  5371.     {
  5372.         PutOp(OP_WIDE);
  5373.         PutOp(OP_IINC);
  5374.         PutU2(var);
  5375.         PutU2(val);
  5376.     }
  5377. }
  5378.  
  5379. void ByteCode::ChangeStack(int i)
  5380. {
  5381.     stack_depth += i;
  5382.     if (stack_depth < 0)
  5383.         stack_depth = 0;
  5384.  
  5385.     if (i > 0 && stack_depth > max_stack)
  5386.         max_stack = stack_depth;
  5387.  
  5388. #ifdef TRACE_STACK_CHANGE
  5389.     Coutput << "stack change: pc "
  5390.             << last_op_pc
  5391.             << " change "
  5392.             << i
  5393.             << "  stack_depth "
  5394.             << stack_depth
  5395.             << "  max_stack: "
  5396.             << max_stack
  5397.             << "\n";
  5398. #endif
  5399.  
  5400.     return;
  5401. }
  5402.  
  5403.  
  5404. #ifdef TEST
  5405. void ByteCode::PrintCode()
  5406. {
  5407.     Coutput << "magic " << hex << magic << dec
  5408.             << " major_version " << (unsigned) major_version
  5409.             << " minor_version " << (unsigned) minor_version << "\n";
  5410.     AccessFlags::Print();
  5411.     Coutput << "\n"
  5412.             << " this_class " << (unsigned) this_class << "  super_class " << (unsigned) super_class <<"\n"
  5413.             << " constant_pool: " << constant_pool.Length() << "\n";
  5414.  
  5415.     {
  5416.         for (int i = 1; i < constant_pool.Length(); i++)
  5417.         {
  5418.             Coutput << "  " << i << "  ";
  5419.             constant_pool[i] -> Print(constant_pool);
  5420.             if (constant_pool[i] -> Tag() == CONSTANT_Long || constant_pool[i] -> Tag() == CONSTANT_Double)
  5421.                 i++; // skip the next entry for eight-byte constants
  5422.         }
  5423.     }
  5424.  
  5425.     Coutput << "  interfaces " << interfaces.Length() <<": ";
  5426.     {
  5427.         for (int i = 0; i < interfaces.Length(); i++)
  5428.              Coutput << "  " << (int) interfaces[i];
  5429.         Coutput <<"\n";
  5430.     }
  5431.  
  5432.     Coutput << "  fields " << fields.Length() <<": ";
  5433.     {
  5434.         for (int i = 0; i < fields.Length(); i++)
  5435.         {
  5436.             Coutput << "field " << i << "\n";
  5437.             fields[i].Print(constant_pool);
  5438.         }
  5439.     }
  5440.  
  5441.     Coutput << " methods length " << methods.Length() << "\n";
  5442.     {
  5443.         for (int i = 0; i < methods.Length(); i++)
  5444.         {
  5445.             Coutput << "method " << i << "\n";
  5446.             methods[i].Print(constant_pool);
  5447.         }
  5448.     }
  5449.  
  5450.     Coutput << " attributes length " << attributes.Length() << "\n";
  5451.     {
  5452.         for (int i = 0; i < attributes.Length(); i++)
  5453.         {
  5454.             Coutput << "attribute " << i << "\n";
  5455.             attributes[i] -> Print(constant_pool);
  5456.         }
  5457.     }
  5458.     Coutput << "\n";
  5459.  
  5460.     return;
  5461. }
  5462. #endif
  5463.